arraysreactjsobjectcheckboxdynamicform

Implement dynamic checkbox with checked handler in React js


I'm having problems setting state for my dynamic checkbox for my array, changing an object from false to true, using a checked handler.

below is my code:

const [form, setForm] = useState({
    tags:[
     { name: "Athletic/Higher caloric", isChecked: false },
     { name: "Aggressive Weight Loss", isChecked: false },
     { name: "Quick and Easy", isChecked: false } ]})

const onCheckedHandler = (index) => {
      const updatedTags = 
        form.tags.map((tag, i) => {
           if (index === i) {
             form.tags[i].isChecked = !form.tags[i].isChecked;
             } 
           return { tag }; 
        }); 

    setForm(updatedTags);


return (
   {form.tags.map((tag, i) => (
        <div>
        <label>{tag.name}</label> 
        <input 
           type="checkbox"
           checked={tag.isChecked}
           onChange={(event) => onCheckedHandler(i)}
           key={i} /> 
        </div>
       ))})

I get this error: "Uncaught TypeError: Cannot read properties of undefined (reading 'map') at Create (line:107)"

But line 107 is just the start of another map function that works and is totally unrelated. What am I doing wrong? I tried avoiding mutating the isChecked value directly in the object with an if statement. Maybe it's how I setState?


Solution

  • It is my understanding that:

    Consequently, please try changing the handler like so:

    const onCheckedHandler = (index) => {
      setForm(prev => ({
        ...prev,
        tags: [
          ...prev?.tags?.map(
            ({isChecked, ...rest}, idx) => (
              idx === index
              ? {...rest, isChecked: !isChecked}
              : {...rest, isChecked}
            )
          )
        ]
      }));
    };
    

    Also, please use checks before attempting map on the return as well. May be try something like so:

    form?.tags?.map(...)

    OR

    form && form.tags && Array.isArray(form.tags) && form.tags.map(...)