How to selectively setState for an object with two array of objects?

Viewed 57

How would I add new objects to the data: [] using setState() for the following code or replace data entirely??

    const [tableState, setTableState] = useState<TableState>({
    columns: [
      { title: "First Name", field: "firstName" },
      { title: "Last Name", field: "lastName" },
    ],
    data: [
      {
        firstName: "John",
        lastName: "Doe",
      },
      {
        firstName: "Jane",
        lastName: "Doe",
      },
    ],
  });

setState(prevState => ({...prevState.tableState, ???}))

2 Answers

You are mixing between hooks and conventional setState.

From the above code, you should be updating your state using setTableState function instead.

setTableState(prevState => ({
  ...prevState,
  data: [
    ...prevState.data,
    {
      firstName: 'New FirstName',
      lastName: 'New Last Name'
    }
  ]
}))

Say you have a new user, Joe Bloggs. It would look like this (note that the setter is setTableState — the setter you got from useState — not setState):

setTableState(prevState => ({
    ...prevState, 
    data: [
        ...prevState.data, {
            firstName: "Joe",
            lastName: "Bloggs"
        }
    ]
}));

What that does:

  1. Creates a new object which is a shallow copy of prevState, but

  2. With a new data property, that

  3. Has the original data, plus the new object


But stepping back a bit: That state item is probably too complicated. With hooks and useState, you usually want to keep your state really finely-grained. In this case, I think there are at least two separate state items:

const [columns, setColumns] = useState<ColumnType[]>([
    { title: "First Name", field: "firstName" },
    { title: "Last Name", field: "lastName" },
]);
const [data, setData] = useState<DataType[]>([
    {
        firstName: "John",
        lastName: "Doe",
    },
    {
        firstName: "Jane",
        lastName: "Doe",
    },
]);

And you'd set new data state like this:

setData(data => [
    ...data,
    {
        firstName: "Joe",
        lastName: "Bloggs"
    }
]);
Related