我开始使用 Shiny 的新 React Hooks 构建我的一些新组件。但是我在我的组件中使用了很多异步 api 调用,在这些组件中我还在获取数据时显示了一个加载微调器。据我理解的概念,这应该是正确的:
const InsideCompontent = props => {
const [loading, setLoading] = useState(false);
useEffect(() => {
...
fetchData()
...
},[])
function fetchData() {
setFetching(true);
apiCall().then(() => {
setFetching(false)
})
}
}
所以这只是我对这可能如何运作的初步想法。只是一个小例子。 但是,如果父组件现在更改了一个条件,即在异步调用完成之前卸载该组件,会发生什么情况。
在我调用 api 回调中的 setFetching(false)
之前,是否有某种检查可以检查组件是否仍然安装?
或者我在这里遗漏了什么?
这是工作示例: https://codesandbox.io/s/1o0pm2j5yq
编辑: 这里没有真正的问题。你可以在这里试试: https://codesandbox.io/s/1o0pm2j5yq
错误来自其他原因,因此使用钩子(Hook),您无需在进行状态更改之前检查组件是否已安装。
使用它的另一个原因:)
最佳答案
您可以使用 useRef
钩子(Hook)存储任何你喜欢的可变值,所以你可以使用它来切换变量 isMounted
到 false
当组件被卸载时,并检查这个变量是否是 true
在您尝试更新状态之前。
示例
const { useState, useRef, useEffect } = React;
function apiCall() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve("Foo");
}, 2000);
});
}
const InsideCompontent = props => {
const [state, setState] = useState({ isLoading: true, data: null });
const isMounted = useRef(true);
useEffect(() => {
apiCall().then(data => {
if (isMounted.current) {
setState({ isLoading: false, data });
}
});
return () => {
isMounted.current = false
};
}, []);
if (state.isLoading) return <div>Loading...</div>
return <div>{state.data}</div>;
};
function App() {
const [isMounted, setIsMounted] = useState(true);
useEffect(() => {
setTimeout(() => {
setIsMounted(false);
}, 1000);
}, []);
return isMounted ? <InsideCompontent /> : null;
}
ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="root"></div>
关于javascript - 使用 React hooks 获取数据清理异步回调,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55122119/