Home > Blockchain >  How can I change boolean property on array object depending on which element was clicked
How can I change boolean property on array object depending on which element was clicked

Time:07-18

const [task, setTask] = useState([{name: 'name1', isChecked: false}, {name: 'name2', isChecked: false}])

I tried this way but it changes on every object:

const handleCheck = (toggle) => {
  setTask(prevState => prevState.map(item => ({
     ...item,
     isChecked: toggle,
  })));

}

CodePudding user response:

Not sure what you are intending exactly, but I'm guessing is that you have a list of objects which reflect a list on the page which can be checked. I suspect you want to have the state update when clicking on an element without updating the entire list? What you did is okay and should work, but if you don't want the entire list to redraw, you should make a 'ListItem' react element, then let that manage it's own internal checked state, and expose a callback when this changes.

An example below:

const ListItem = ({name, defaultChecked, callback}) => {
  const [checked, setChecked] = useState(defaultChecked);

  const toggleChecked = () => {
       setChecked(!checked)
       callback(checked)
  }

  return <div>
     <button onClick={() => toggleChecked()}>{checked}</button>
     <div>{name}</div>
  </div>
}

Naturally you'll update the HTML to make sense for your case. And remember this is just an option which internally managed the checked state, and there are cases where you don't want this and prefer to implement it as you have above.

CodePudding user response:

Just, pass index of the element that you clicked and then toggle the isChecked property using the index.

function App(){
    const [task, setTask] = useState([{name: 'name1', isChecked: false}, {name: 'name2', isChecked: false}])
    
   const handleCheck = (index) => {
      let new_array = task;
      new_array[index].isChecked = !new_array[index].isChecked;
      setTask(new_array);
   }

   return (
        <>
           {
              task.map((__task,index) => 
                 <div key={index} 
                   onClick={() => handleClick(index)} 
                 >
                 {__task.name}
                 </div>
           }
        </>
     )
}

CodePudding user response:

First thing: You should get the task name which you checked. Then you could code like this:

const hadleCheck = (checkName) => {
  setTask((prevState) =>
    prevState.map((item) => ({
      ...item,
      isChecked: checkName === item.name ? true : false,
    }))
  );
};

CodePudding user response:

You can use below code:

const [task, setTask] = useState([{ name: 'name1', isChecked: false }, { name: 'name2', isChecked: false }])

    const handleCheck = (task) => {
        setTask(prevState => prevState.map(item => {
            if (item.name === task.name) {
                return {
                    ...item,
                    isChecked: !item.isChecked,
                }
            }
            return item
        }));
    }

    return (
        <div style={{ display: 'flex', flexDirection: 'column' }}>
            {
                task.map((task, i) => (
                    <div key={i}>
                        <span>{task.name}</span>
                        <input type="checkbox" onChange={() => handleCheck(task)} />
                    </div>
                ))
            }
        </div>
    );
  • Related