I have the following code:
const classes = useStyles();
const [data1, setData1] = useState([]);
const [searchedString, setSearchString] = useState("");
console.log(data1);
const fetchDataHandler = async () => {
setData1([]);
axios
.get(`http://localhost:5000/select?articul=${searchedString}`)
.then((response) => {
dataStruction(response.data);
})
.catch((err) => {
console.log(err);
});
};
const dataStruction = (data) => {
data.map((element1) => {
if (element1.secondaryArt.startsWith("30")) {
return setData1([...data1, { ...element1, level: 1 }]);
}
});
};
const onChangeSearchText = (event) => {
setSearchString(event.target.value);
};
I want whenever I call fetchDataHandler to be able to set data1 to empty array. Now it is working as that results are sticking every time I call fetchDataHandler. How can I do it?
Problem:
Your Asynchronous handler dataStruction
closes over data1
before a new render is triggered at setData1([]);
(at the top of your async
function).
This happens because React state updates are batched and asynchronous.
Simple Solution:
If you get rid of (delete the line) setData1([]);
and change setData1([...data1, { ...element1, level: 1 }]);
to setData1([{ ...element1, level: 1 }]);
then you will get an array with a new element in it without preserving the "old" elements.
Alternative Solution:
You can also wrap your state updates into functions like so:
Turn this: setState("foo")
Into this: setState((state, props) => "foo")
The second form (passing a function instead directly a state) ensures that the correct state is referenced. So in your case the second state update would reference the updated state.