dimanche 14 mars 2021

How do I Map several controlled input checkboxes from an array in React?

I'm trying to make a number of controlled checkboxes from an array like so

const subjects = [
    {
      name: 'WebDev',
      label: 'Web Development',
    },
    {
      name: 'GraphicDesign',
      label: 'Graphic Design',
    },
    {
      name: 'Engineering',
      label: 'Engineering',
    },
  ];

I want to make them controlled, so for the checked attribute, I need it to be controlled by state. But how do I loop through them and access the correct object in state each time? I guess I could maybe parse the subject.name string, but surely that is not good practice? Indeed, I could perhaps make a matching array in my state where the indexes match up, but I don't feel like that is scalable and relies heavily on correct order.

{subjects.map((subject, i) => (
  <div className="w-full sm:w-auto" key={i}>
  <label className="flex content-center p-3">
    <input type="checkbox" name={subject.name} value={subject.name} onChange={onInputChange} checked={????}/>
    <span className="ml-3">{subject.label}</span>
  </label>
</div>
))}

I also have other inputs like this. For them, it is easy because I can just use state.name to control them.

      <input id="name" type="text" value={state.name} onChange={onInputChange} name="name" required/>

I then use a generalised function to update the inputs. This takes use of the useState() Hook

    const onInputChange = e => {

    const item = e.target.name;
    const value = e.target.type === "checkbox" ? e.target.checked : e.target.value;

    setState({
      ...state,
      [item]: value,
    })
  }

What is the best practice in React for approaching something like this? If I could contain the subjects in my state as shown below it would be good.

Should I maybe be ditching the seperate array and containing all the information in state?

const [state, setState] = useState({
    name:'',
    email: '',
    message: '',
    checkedSubs: {
      WebDev: false,
      GraphicDesign: false,
      Engineering: false
    },
    emailSent: false
})

Thanks!




Aucun commentaire:

Enregistrer un commentaire