【问题标题】:React setState inside useCallback() hook not setting state variable correctly?在 useCallback() 钩子中反应 setState 没有正确设置状态变量?
【发布时间】:2020-08-24 19:11:39
【问题描述】:

我在 React FunctionComponent 中有以下模式的代码:

const MyComponent: React.FunctionComponent<ISomeInterface> = ({ someArray, someFunction }) => {

  const [someStateObjVar, setSomeStateObjVar] = React.useState({});
  const [isFound, setIsFound] = React.useState(false);

  const handleSomeEvent = React.useCallback((someAttribute: string) => {
    if (someAttribute) {
      setSomeStateObjVar(someArray.find(
        (arrayElement) => ( arrayElement.attribute === someAttribute )
      );
      setIsFound(someStateVar ?? false);
    }
  }
  
  return ( isFound && someStateObjVar ) ? <FoundMatchingComponent /> ? <ComponentNotFound />;

在上面的代码中,someArray 元素总是与 someAttribute 匹配。 但问题是 MyComponent 总是呈现 ComponentNotFound 因为 isFound 总是在最后一行(return 语句)计算为 FALSE。

我能够通过以下重构解决此问题(插入一个中间变量,但总体逻辑保持不变):

const MyComponent: React.FunctionComponent<ISomeInterface> = ({ someArray, someFunction }) => {

  const [someStateObjVar, setSomeStateObjVar] = React.useState({});
  const [isFound, setIsFound] = React.useState(false);

  const handleSomeEvent = React.useCallback((someAttribute: string) => {
    let foundElement;
    if (someAttribute) {
      foundElement = someArray.find(
        (arrayElement) => ( arrayElement.attribute === someAttribute )
      );
    }
    if (foundElement) {
      setSomeStateObjVar(foundElement);
      setIsFound(true);
    }
  }
  
  return ( isFound && someStateObjVar ) ? <FoundMatchingComponent /> ? <ComponentNotFound />;

使用此第二版代码,isFound 在最后一行正确地计算为 TRUE,并且 MyComponent 正确地呈现 FoundMatchingComponent。

您能否解释一下为什么第一个版本不起作用,而第二个版本起作用?

我的猜测是,第二个版本中的中间变量为 React 提供了足够的时间在 return 语句中正确评估 isFound 变量,但我不确定这就是解释。任何关于改进我上面的代码的建议也将不胜感激。谢谢。

【问题讨论】:

  • 在第一个代码中,您调用setState() 太早了,因为在 React 中,状态不会立即更新。由于isFound 取决于第一个状态,因此您必须使用useEffect 在设置isFound 之前观察第一个状态何时发生变化,或者像您已经在做的那样使用您的第二个解决方案。
  • 谢谢@IsraelObanijesu,你是对的。我需要记住,设置状态变量不会立即更新,而是由 React 批处理。此外,您能否提供有关如何使用 useEffect 解决原始问题的更多详细信息。我不确定我是否遵循您的建议,但很想知道。谢谢

标签: javascript reactjs typescript usecallback


【解决方案1】:

在第一个代码 sn-p 中,我看不到 someStateVar 的定义位置。如果是这种情况,变量是undefined,所以setIsFound(someStateVar ?? false) 将始终评估为假。因此,isFound 为 false,return 语句将始终返回 &lt;ComponentNotFound /&gt;

您是否打算拥有setIsFound(someStateObjVar ?? false)

【讨论】:

    猜你喜欢
    • 2020-04-26
    • 1970-01-01
    • 2020-02-22
    • 2019-07-31
    • 1970-01-01
    • 1970-01-01
    • 2021-06-13
    • 2020-11-30
    • 2020-03-09
    相关资源
    最近更新 更多