Home > Mobile >  map over nested object in an array
map over nested object in an array

Time:08-11

Currently trying to map over an array that has multiple nested objects. When I run the map function, it only returns the outer object.

enter image description here

const [moreDetails, setMoreDetails] = useState([]);
const [details, setDetails] = useState("");

const handleAddMoreDetails = () => {
  setMoreDetails((prevState) => [
    {
      ...prevState,
      details: details
    }
  ]);
  setDetails("");
};

return (
  <div className="App">
    <input
      type="text"
      value={details}
      onChange={(e) => setDetails(e.target.value)}
    />

    <button onClick={handleAddMoreDetails}>Add Detail</button>

    {moreDetails &&
      moreDetails.map((item, index) => <p key={index}>{item.details}</p>)}
  </div>
);

This is similar to what I am trying to accomplish. I would like for it to render all of them when added. I am thinking it may be the one I am trying to add a new detail

CodeSandbox

CodePudding user response:

The problem isn't in the rendering, it's in the state update:

setMoreDetails((prevState) => [
  {
    ...prevState,
    details: details
  }
]);

If prevState was an array, for example:

[
  { details: 'first record' }
]

Then what happens after your state update? This update is creating an array with one object, which contains both the previous array and the new object. So the new result is:

[
  {
    0: {
      details: 'first record'
    },
    details: 'second record'
  }
]

Each update to the state will continue to create an array with one object, nesting the previous array inside that object.

Instead, create an array containing the elements of the previous array plus the one new object:

setMoreDetails((prevState) => [
  ...prevState,
  {
    details: details
  }
]);

So the new state would be:

[
  { details: 'first record' },
  { details: 'second record' }
]
  • Related