Javascript 为什么我们需要在React钩子中返回一个函数?
我正在项目中使用Material UI组件,并在我的应用程序中使用Javascript 为什么我们需要在React钩子中返回一个函数?,javascript,reactjs,material-ui,Javascript,Reactjs,Material Ui,我正在项目中使用Material UI组件,并在我的应用程序中使用AutoComplete组件 在Material UI团队的示例中,我遇到了一个自动完成Ajax数据的有趣示例: 他们正在使用React钩子从服务器获取数据: React.useEffect(() => { let active = true; if (!loading) { return undefined; } (async () => { const r
AutoComplete
组件
在Material UI团队的示例中,我遇到了一个自动完成Ajax数据的有趣示例:
他们正在使用React钩子从服务器获取数据:
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]);
为什么我们在这里使用active
变量?为什么我们返回一个函数将此变量更改为false
?在if语句中总是true
。
提前感谢您的回答这是一种用于避免两种情况的模式:
如果包含此钩子的组件在HTTP请求完成之前已卸载,则更新状态
避免比赛条件
由useffect
hook的回调函数返回的函数用于执行清理,如基于类的组件中的componentWillUnmount
。此清理功能在组件卸载时或下次运行效果之前运行
因此,如果在HTTP请求进行时卸载了组件,useEffect钩子的清理功能将运行,并将active
设置为false。之后,无论何时HTTP请求的结果返回,状态都不会更新,因为active
将为false
请参阅react docs的一节,了解useEffect
钩子的清除功能,并参阅,更好地了解通过使用active
变量解决的与竞态条件相关的问题。从useEffect
返回的函数是一个函数。它在组件卸载时调用,通常用于取消订阅useffect
中使用的事件、取消挂起的承诺等
使用active
变量确保您没有更新不再存在的对象的状态。这有点像类组件中存在的反模式
当您尝试更新未安装组件的状态时,React将抛出警告-
警告:无法对已卸载的组件执行React状态更新。这是一个no-op,但它表示应用程序中存在内存泄漏
激活变量可以通过以下方式防止:
- 您的组件已加载
useffect
调用一个async
fetch-这需要时间
- 现在,假设在返回响应中的服务器之前,您导航离开页面(或者执行其他一些取消装载组件的操作)
- 这将导致卸载组件并调用清理函数:
active
现在设置为false
- 最后,我们从服务器得到响应。现在,它将遇到
false
active
值,并且不会更新状态李>
return () => {
active = false;
};
// active === false,
// this will skip `setOptions`
if (active) {
setOptions(...);
}