【问题标题】:React: Suspended component doesn't run the useEffect hook反应:暂停的组件不运行 useEffect 钩子
【发布时间】:2019-07-07 18:49:20
【问题描述】:

目前正在尝试反应钩子和反应悬念。我正在尝试制作一个钩子useApolloQuery,它会获取一些数据并承诺等待数据加载。

我将获取数据的逻辑放在 useEffect 中,但如果你立即在组件中抛出一个 promise(并因此暂停它),效果似乎永远不会运行。

这是我的代码:(或代码框链接: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 钩子永远不会运行

悬念应该这样运作吗?有什么办法让它工作吗?

【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:

    useEffect 没有运行,因为您在实际函数返回之前抛出了一个 Promise,所以这个 Promise 永远不会被解决。

    问题出在一行

    if (!data) throw promsieResolver.promise;

    初始data 未定义,因此!data = true。它抛出一个承诺,因此该函数永远不会返回,而是短路。删除此行实际上运行 useEffect 挂钩

    解决方案 2: 或者您可以为undefined 以外的数据设置初始状态,如下所示 const [data, setData] = useState('initial data');

    【讨论】:

    • 是的,我发现你用钩子做的所有事情在挂起时都会被扔掉,所以你需要在外部存储中保留任何状态
    【解决方案2】:

    刚刚发现:https://github.com/facebook/react/issues/14563#issuecomment-453184356 所以看起来除了将所有状态保存在外部存储中之外没有其他办法

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-12-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-12
      • 2019-08-21
      • 2022-01-08
      • 1970-01-01
      相关资源
      最近更新 更多