简体   繁体   中英

Updating state onChange for an array within an array react hooks

I have an array of objects and those objects also have arrays of objects. I'd like to update an object value in the array that is inside an array of objects.

example -

const [datas, setDatas] = useState([
    {
      id:   1,
      name: 'john',
      gender: 'm'
      cars: [{name: 'fiat', colour: 'blue', engine: 'massive'}
             {name: 'ferrari', colour: 'red', engine: 'tiny'}]
    }
    {
      id:   2,
      name: 'mary',
      gender: 'f'
      cars: [{name: 'lambo', colour: 'black', engine: 'big'}
             {name: 'bugatti', colour: 'brown', engine: 'small'}]
    }
]);

const updateFieldChanged = index => e => {

    
    let newArr = [...datas]; 
    newArr[index] = e.target.value; 

    
}
const updateCarFieldChanged = index => e => {

    ???????????
    }


return (
    <React.Fragment>
        { datas.map( (data, index) => {
              <li key={data.name}>
                <input type="text" name="name" value={data.name} onChange={updateFieldChanged(index)}  />
              </li>
          { data.cars.map( (car, index) => {
              <li key={car.name}>
                <input type="text" name="name" value={car.name} onChange={updateCarFieldChanged(index)}  />
              </li>

})
        }
    </React.Fragment>
)

I know how to update the objects in the first array, as the code shows (example code, please ignore the small things like using name for the key), but having trouble targeting object values in the objects in the second array, and updating those.

Hope that is clear.

There are quite a few issues with the code you posted. You're missing commas, brackets and parentheses in places.

You could do something like this where you pass the index of the datas , the index of the car , and the event to get the name and value of the input.

const [datas, setDatas] = useState([
  {
    id: 1,
    name: 'john',
    gender: 'm',
    cars: [{ name: 'fiat', colour: 'blue', engine: 'massive' },
    { name: 'ferrari', colour: 'red', engine: 'tiny' }]
  },
  {
    id: 2,
    name: 'mary',
    gender: 'f',
    cars: [{ name: 'lambo', colour: 'black', engine: 'big' },
    { name: 'bugatti', colour: 'brown', engine: 'small' }]
  }
]);

const updateFieldChanged = index => e => {


  let newArr = [...datas];
  newArr[index] = e.target.value;


}
const updateCarFieldChanged = (dataIndex, carIndex, event) => {
  const { name, value } = event;
  const newData = {
    ...datas, // spread all the datas objects.
    [dataIndex]: { // for the index of the datas we're going to update
      ...datas[dataIndex], // spread the rest of that datas object we're updating
      cars: [ // set the cars data object since we will be updating that object
        ...datas[dataIndex].cars, // spread all other properties of the car
        [carIndex]: { // update the car based on the index
          ...datas[dataIndex].cars[carIndex], // spread the rest of the car object
          [name]: value // update the property with the new value.
        }
      ]
    }
  }
  setDatas(newData)
}


return (
  <React.Fragment>
    { datas.map((data, i) => {
      <li key={data.name}>
        <input type="text" name="name" value={data.name} onChange={updateFieldChanged(i)} />
      </li>
      {
        data.cars.map((car, index) => {
          <li key={car.name}>
            <input type="text" name="name" value={car.name} onChange={(e) => updateCarFieldChanged(i, index, e)} />
          </li>
        })
      }
    })}
  </React.Fragment>
)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM