I'm working with Material-UI components on the project and is using AutoComplete component in my app.
In the example from Material-UI team, I came across an interesting example of the AutoComplete Ajax data: https://material-ui.com/components/autocomplete/#asynchronous-requests
They are using React Hooks to fetch the data from the server:
React.useEffect(() => {
let active = true;
if (!loading) {
return undefined;
}
(async () => {
const response = await fetch('https://country.register.gov.uk/records.json?page-size=5000');
await sleep(1e3); // For demo purposes.
const countries = await response.json();
if (active) {
setOptions(Object.keys(countries).map((key) => countries[key].item[0]));
}
})();
return () => {
active = false;
};
}, [loading]);
Why do we use active variable here? Why we return a function that changes this variable to false? It is always true in the if-statement.
Thanks in advance for the answer
The function returned from useEffect is a cleanup function. It is called when the component un-mounts - and is usually used to unsubscribe to events, cancel pending promises etc that were used in the useEffect.
The active variable is used make sure that you aren't updating the state on something that doesn't exist anymore. It's somewhat like the isMounted anti-pattern that existed in class components.
When you try to update state on an un-mounted component, React will throw a warning -
Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application.
Having the active variable prevents that in the following way:
useEffect calls an async fetch - this will take time return () => {
active = false;
};
active is now set to falsefalse active value, and not update the state. // active === false,
// this will skip `setOptions`
if (active) {
setOptions(...);
}
This is a pattern which is used to avoid two situations:
Function returned by callback function of useEffect hook is used to perform the clean up, like componentWillUnmount in class based components. This cleanup function runs when the component unmounts or before running the effect next time.
So if component is unmounted when the HTTP request was in progress, cleanup function of useEffect hook will run and will set active to false. After that, whenever the result of HTTP request returns, state won't be updated because active will be false.
See Effects with cleanup section of react docs to understand the cleanup function of useEffect hook and see Race Conditions to better understand the problem related to race conditions that is solved here by using active variable.
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