【问题标题】:Run react hook inside variable for-loop在变量 for 循环中运行反应钩子
【发布时间】:2019-08-11 15:45:29
【问题描述】:

这是用例。我们单独的 AJAX 调用在一个钩子后面(我们使用 apollo 钩子)。但是,有时我们需要进行可变数量的调用(可变 for 循环)。初始 AJAX 调用决定了对另一个端点进行多少变量调用。不幸的是,这段代码没有运行(React 运行时错误):

https://jsfiddle.net/dm3b2Lgh/

我看过这个其他问题,但给定的方法不起作用:Why can't React Hooks be called inside loops or nested function?

有没有办法让它工作?

function useInitialAjaxCall() {
    const [result, setResult] = React.useState(0);
  React.useEffect(() => {
    const resultSize = Math.floor((Math.random() * 100) + 1);
    Promise.resolve().then(() => setResult(
            resultSize
    ))
  }, [])
  return result;
}

function useMockAjaxCall(i) {
    const [result, setResult] = React.useState();
  React.useEffect(() => {
    Promise.resolve().then(() => setResult(i));
  }, [i])
  return result;
}

function useMakeNCalls(n) {
   return [...Array(n)].map((_, i) => useMockAjaxCall(i));
}

function useCombineAjaxCalls(n) {
    const resultArray = useMakeNCalls(n);
    const resultCombined = React.useMemo(() => {
    return resultArray.reduce((total, cur) => total + cur, 0);
  }, [resultArray])
  return resultCombined;
}

function Hello(props) {
  const initial = useInitialAjaxCall();
  const count = useCombineAjaxCalls(
        initial
  );
  return (
  <div>
  <div>{initial}</div>
  <div>{count}</div>
  </div>
  );
}

ReactDOM.render(
  <Hello name="World" />,
  document.getElementById('container')
);

【问题讨论】:

  • 那么...问题是什么?

标签: reactjs react-hooks


【解决方案1】:

original question 询问一个固定的 for 循环:

如果我们在迭代次数不随时间变化的循环中调用 useState

但是,在您的代码中,useInitialAjaxCall() 将在第一次渲染期间返回 undefined(因为 useEffect 是异步的 - 它将在第一次渲染后执行)。

然后,useCombineAjaxCalls(undefined) 将调用useMakeNCalls(undefined),后者将调用useMockAjaxCall(0),只调用一次useState

在第一次渲染结束时,initial 将是 undefinedcount 将是 NaN

假设 resultSize 与 1 不同,在下一次渲染中,您的代码将尝试调用 useState 的次数与 1 不同,如原问题所述,这是不可能的。

不可能“在变量 for 循环中运行反应钩子” - 但您可以创建 1 个状态,即一个数组。

【讨论】:

  • 我拼凑的代码中有一个错误 --- 我更新为在初始调用时始终返回一个数字。仍然是同样的错误
  • 您是说不可能做我们想做的事吗?除了手动进行 n 个 AJAX 调用(没有挂钩)之外,没有其他办法吗?
  • 我是说不可能有可变数量的钩子。我不确定您要做什么,但是您始终可以使用固定数量的挂钩来获取任意数量的数据,例如const [data, setData] = useState([]); Promise.all(xxx).then((results) =&gt; setData(results))
猜你喜欢
  • 1970-01-01
  • 2022-01-04
  • 1970-01-01
  • 1970-01-01
  • 2015-08-30
  • 2017-09-07
  • 1970-01-01
  • 2022-01-18
  • 2021-04-10
相关资源
最近更新 更多