在变量for循环内运行react hook

时间:2019-08-11 15:45:29

标签: reactjs react-hooks

这是用例。我们单独的AJAX调用位于一个钩子后面(我们使用apollo钩子)。但是,有时我们需要进行可变数量的调用(可变for循环)。最初的AJAX调用确定要对另一个端点进行多少次变量调用。不幸的是,此代码无法运行(反应运行时错误):

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')
);

1 个答案:

答案 0 :(得分:2)

original question正在询问固定的for循环:

  

如果我们在循环内调用useState,则迭代次数不会随时间变化

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

然后,useCombineAjaxCalls(undefined)将呼叫useMakeNCalls(undefined),后者将呼叫useMockAjaxCall(0),仅呼叫useState

在第一次渲染结束时,initial将为未定义,而count将为 NaN

假设resultSize与1不同,在下一个渲染中,您的代码将尝试调用useState而不是1,这与原始问题中所解释的不同。

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