Use the spread syntax to push an element into a state array in React, e.g. setNames(current => [... current, 'Carl']) . The spread syntax (...) will unpack the existing elements of the state array into a new array where we can add other elements.
useState is a Hook that allows you to have state variables in functional components. You pass the initial state to this function and it returns a variable with the current state value (not necessarily the initial state) and another function to update this value.
The React useState Hook allows us to track state in a function component. State generally refers to data or properties that need to be tracking in an application.
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>
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
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]);
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.
The same way you do it with "normal" state in React class components.
example:
function App() {
const [state, setState] = useState([]);
return (
<div>
<p>You clicked {state.join(" and ")}</p>
//destructuring
<button onClick={() => setState([...state, "again"])}>Click me</button>
//old way
<button onClick={() => setState(state.concat("again"))}>Click me</button>
</div>
);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With