Push Method in React Hooks (Usestate)

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



Leave a reply



Submit