目前正在尝试反应钩子和反应悬念。我正在尝试制作一个钩子useApolloQuery
,该钩子将获取一些数据并发出承诺,直到数据加载完毕。
我正在使用逻辑来获取useEffect
中的数据,但是,如果您立即在组件中抛出诺言(并因此将其挂起),似乎效果永远不会得到发挥。
这是我的代码:(或codeandbox链接:https://codesandbox.io/s/x73pwj164q)
function createPromiseResolver() {
let resolve;
const promise = new Promise(newResolver => {
resolve = newResolver;
});
return { resolve, promise };
}
function useApolloQuery() {
const [data, setData] = useState();
const promsieResolver = createPromiseResolver();
console.log("this runs");
useEffect(() => {
console.log("this doesn't run");
const timeoutId = setTimeout(() => {
setData("Some fake data");
promsieResolver.resolve();
}, 500);
return () => clearTimeout(timeoutId);
});
if (!data) throw promsieResolver.promise;
return data;
}
function App() {
const data = useApolloQuery();
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<h2>{data}</h2>
</div>
);
}
因此在该代码中,仅第一个console.log运行,因为useEffect钩子永远不会运行
悬疑应该这样吗?有什么办法可以使它起作用?
答案 0 :(得分:1)
useEffect
无法运行,因为您在实际函数返回之前就抛出了一个诺言,因此该诺言从未得到解决。
问题出在那
if (!data) throw promsieResolver.promise;
未定义初始data
,因此!data = true
未定义。它抛出了一个承诺,因此该函数从不返回而是短路。删除此行实际上会运行useEffect
钩子
解决方案2:
或者,您可以为undefined
以外的数据设置初始状态,如下所示
const [data, setData] = useState('initial data');
答案 1 :(得分:0)
刚刚发现了这一点:https://github.com/facebook/react/issues/14563#issuecomment-453184356 因此,除了将所有状态保留在外部存储中之外,似乎没有其他解决办法