Push method in React Hooks (useState)?
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>
How to push new value in array useState in react
Your problem is you scoped your states only in MovieCard
which means each MovieCard
will have different states.
You need to add states on the upper/parent component of MovieCard
. Let's assume you have MovieList
contains all MovieCard
const MovieList = () => {
const [firstCat, setFirstCat] = React.useState([]);
console.log(firstCat);
return <div>
<MovieCard movie={movie} setFirstCat={setFirstCat}/>
<div/>
}
And modify your MovieCard
like below
const MovieCard = ({ movie, setFirstCat }) => {
const movieList = (movie) => {
setFirstCat([...firstCat, movie]);
}
return (
<div className='mt-3 cursor-pointer' onClick={() => movieList(movie)}>
<div className="max-w-sm bg-white rounded-lg border border-gray-200 shadow-md">
<img className="rounded-t-lg" src="/docs/images/blog/image-1.jpg" alt="" />
<div className="p-5">
<h5 className="mb-2 text-xl font-bold tracking-tight text-gray-900">{movie.Title}</h5>
</div>
</div>
</div>
);
};
export default MovieCard;
This technique is called state lifting
How to push to state in React Hooks?
My assumption is that you expect the filteredProducts
state value to reflect your changes right after setFilteredProducts
:
setFilteredProducts((currentFilteredProducts) => [
...currentFilteredProducts,
...productsToAdd,
]);
dispatch({
type: "PRODUCTS_FILTERED",
payload: filteredProducts,
});
Unfortunately, that's not how state updates work. The set*
function simply queues the update for the next render, but does not immediately update the state.
You could maintain a local variable to pass the update both into the local state and into the Redux store:
const updatedProducts = [
...filteredProducts,
...productsToAdd,
];
setFilteredProducts(updatedProducts);
dispatch({
type: "PRODUCTS_FILTERED",
payload: updatedProducts,
});
How to push a new value into the current array using the react hooks?
react will not rerender if setState return the same state that was before.
when you use the push method you mutate the state object.
instead create a new array with the new item.
always update your state in immutable way.
in your case:
onClick={() => {
setArr((prevArr) => ([...prevArr, prevArr.length + 1]));
}}
How to push an object in an array, using react hooks and typscript?
The issue is that you are saving the result of the push, the new length, instead of the updated array.
setListArray([...listArray].push(myNewList)); // <-- saves result of push, [].length
You can concat
the new element:
setListArray([...listArray].concat(myNewList));
Or just append it
setListArray([...listArray, myNewList]);
Additional semi-related issue, you can't console log the state and expect to see it immediately updated.
setListArray([...listArray, myNewList]);
console.log(listArray); // <-- still current state
React state updates are asynchronous, so logging the state like this will only ever log the state from the current render cycle and not the enqueued state for the next render cycle. If you want to log state after an update use an useEffect
hook with dependency.
useEffect(() => {
console.log(listArray);
}, [listArray]);
Adding an element to an existing array in react hooks
While you could spread the existing Class
into a new object, and then spread the new students
array into that new object as well, it would be better to follow the convention and separate out the state variables (as React recommends), and to not use Class
as a variable name (it's very close to the reserved word class
). Consider:
const [teacher, setTeacher] = useState('John Fartsalot');
const [year, setYear] = useState(2021);
const [students, setStudents] = useState([]);
Then to add to the students array, do
setStudents([...students, studentObject]);
Or, if students
happens to be in a stale closure at this point, then
setStudents(students => [...students, studentObject]);
push an element to an array with useState hooks
Use the updater
version of the setter provided by useState
and concat
to return a new array instead of push
const handleAddChip = chip => {
setData(previousData =>({
...previousData,
tags: previousData.tags.concat(chip)
}));
};
You can also do it without the updater version, but usually isn't a good idea.
setData({...myData, tags: myData.tags.concat(chip)})
Related Topics
Getelementsbyclassname() Doesn't Work in Old Internet Explorers Like IE6, IE7, IE8
How to Fix Navigator/Window/Document Is Undefined in Nuxt
How Does 'Array.Prototype.Slice.Call' Work
How to Create an Https Server in Node.Js
How Does _Proto_ Differ from Constructor.Prototype
What's a Good Way to Extend Error in JavaScript
Accessing Redux State in an Action Creator
Web Workers Without a Separate JavaScript File
How to Custom-Format the Autocomplete Plug-In Results
Getting a Better Understanding of Callback Functions in JavaScript
Difference Between HTMLcollection, Nodelists, and Arrays of Objects
Jquery's .Click - Pass Parameters to User Function
How to Implement Routereusestrategy Shoulddetach for Specific Routes in Angular 2
How to Mock an Es6 Module Import Using Jest
Javascript/Jquery to Download File via Post with JSON Data
What's the Fastest Way to Loop Through an Array in JavaScript