React: What is the difference between const newArray = oldArray and const newArray = [...oldArray] [duplicate]

How to push element inside useState array React hook? Is that as an old method in react state? Or something new?

E.g. setState push example ?


Solution 1:

When you use useState, you can get an update method for the state item:

const [theArray, setTheArray] = useState(initialArray);

then, when you want to add a new element, you use that function and pass in the new array or a function that will create the new array. Normally the latter, since state updates are asynchronous and sometimes batched:

setTheArray(oldArray => [...oldArray, newElement]);

Sometimes you can get away without using that callback form, if you only update the array in handlers for certain specific user events like click (but not like mousemove):

setTheArray([...theArray, newElement]);

The events for which React ensures that rendering is flushed are the "discrete events" listed here.

Live Example (passing a callback into setTheArray):

const {useState, useCallback} = React;
function Example() {
    const [theArray, setTheArray] = useState([]);
    const addEntryClick = () => {
        setTheArray(oldArray => [...oldArray, `Entry ${oldArray.length}`]);
    };
    return [
        <input type="button" onClick={addEntryClick} value="Add" />,
        <div>{theArray.map(entry =>
          <div>{entry}</div>
        )}
        </div>
    ];
}

ReactDOM.render(
    <Example />,
    document.getElementById("root")
);
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.1/umd/react-dom.production.min.js"></script>

Because the only update to theArray in there is the one in a click event (one of the "discrete" events), I could get away with a direct update in addEntry:

const {useState, useCallback} = React;
function Example() {
    const [theArray, setTheArray] = useState([]);
    const addEntryClick = () => {
        setTheArray([...theArray, `Entry ${theArray.length}`]);
    };
    return [
        <input type="button" onClick={addEntryClick} value="Add" />,
        <div>{theArray.map(entry =>
          <div>{entry}</div>
        )}
        </div>
    ];
}

ReactDOM.render(
    <Example />,
    document.getElementById("root")
);
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.1/umd/react-dom.production.min.js"></script>

Solution 2:

To expand a little further, here are some common examples. Starting with:

const [theArray, setTheArray] = useState(initialArray);
const [theObject, setTheObject] = useState(initialObject);

Push element at end of array

setTheArray(prevArray => [...prevArray, newValue])

Push/update element at end of object

setTheObject(prevState => ({ ...prevState, currentOrNewKey: newValue}));

Push/update element at end of array of objects

setTheArray(prevState => [...prevState, {currentOrNewKey: newValue}]);

Push element at end of object of arrays

let specificArrayInObject = theObject.array.slice();
specificArrayInObject.push(newValue);
const newObj = { ...theObject, [event.target.name]: specificArrayInObject };
theObject(newObj);

Here are some working examples too. https://codesandbox.io/s/reacthooks-push-r991u

Solution 3:

You can append array of Data at the end of custom state:

  const [vehicleData, setVehicleData] = React.useState<any[]>([]);
  setVehicleData(old => [...old, ...newArrayData]);

For example, In below, you appear an example of axios:

  useEffect(() => {
    const fetchData = async () => {
      const result = await axios(
        {
          url: `http://localhost:4000/api/vehicle?page=${page + 1}&pageSize=10`,
          method: 'get',
        }
      );
      setVehicleData(old => [...old, ...result.data.data]);
    };

    fetchData();
  }, [page]);

Solution 4:

Most recommended method is using wrapper function and spread operator together. For example, if you have initialized a state called name like this,

const [names, setNames] = useState([])

You can push to this array like this,

setNames(names => [...names, newName])

Hope that helps.

Solution 5:

Creating an Array State with useState() First, let's see how to use the useState() hook for creating an array state variable.

import React from "react";

const { useState } = React;

const [myArray, setMyArray] = useState([]);

However, with React, we need to use the method returned from useState to update the array.

setMyArray(oldArray => [...oldArray, newElement]);

know more