import { useEffect, useState } from "react";
export default function App() {
const [criteria, setCriteria] = useState({});
const handleCriteriaChange = (values) => {
// setCriteria(prevCriteria => ({
// ...prevCriteria,
// ...values
// }))
setCriteria({
...criteria,
...values
});
};
useEffect(() => {
setTimeout(() => {
handleCriteriaChange({
courses: ["calculus", "psychology"]
});
}, 1000);
setTimeout(() => {
handleCriteriaChange({
type: "manual"
});
}, 5000);
setTimeout(() => {
handleCriteriaChange({
termLengths: [14, 7]
});
}, 10000);
// eslint-disable-next-line
}, []);
console.log({ criteria: JSON.stringify(criteria) });
return (
<div className="App">
<h1>Hello CodeSandbox {JSON.stringify(criteria)}</h1>
<h2>Start editing to see some magic happen!</h2>
</div>
);
}
I've added a logic to update state object with different keys in 5 seconds gap between each update. And I was expecting all key values appear in the state object, but only the last state update is displaying. Why I can't get all the added key: values? Even if there's a state batching they are updating state with different keys.
the issue with your update state function handleCriteriaChange. variable criteria is empty in useEffect function and when you use it or assign it. you have to use the previous state value while updating the state.
import React from 'react';
import { useEffect, useState } from 'react';
export default function App() {
const [criteria, setCriteria] = useState({});
const handleCriteriaChange = (values) => {
setCriteria(prev=> ({
...prev,
...values,
}));
};
useEffect(() => {
setTimeout(() => {
handleCriteriaChange({
courses: ['calculus', 'psychology'],
});
}, 1000);
setTimeout(() => {
handleCriteriaChange({
type: 'manual',
});
}, 5000);
setTimeout(() => {
handleCriteriaChange({
termLengths: [14, 7],
});
}, 10000);
// eslint-disable-next-line
}, []);
console.log({ criteria: JSON.stringify(criteria) });
return (
<div className="App">
<h1>Hello CodeSandbox {JSON.stringify(criteria)}</h1>
<h2>Start editing to see some magic happen!</h2>
</div>
);
}