在功能组件中使用回调对 setState 进行反应

Posted

技术标签:

【中文标题】在功能组件中使用回调对 setState 进行反应【英文标题】:React setState with callback in functional components 【发布时间】:2020-09-02 13:16:15 【问题描述】:

我在类组件中写了一个非常简单的例子:

    setErrorMessage(msg) 
      this.setState(error_message: msg, () => 
          setTimeout(() => 
              this.setState(error_message: '')
          , 5000);
      );
    

所以我在这里调用setState() 方法并给它一个回调作为第二个参数。

我想知道我是否可以使用 useState 钩子在功能组件中执行此操作。

据我所知,您不能将回调传递给该钩子的 setState 函数。当我使用 useEffect 钩子时,它会陷入无限循环:

所以我猜 - 这个功能不包含在功能组件中?

【问题讨论】:

【参考方案1】:

react-hooks 中不提供回调功能,但您可以使用 useEffectuseRef 编写一个简单的解决方法。

const [errorMessage, setErrorMessage] = useState('')
const isChanged = useRef(false);
useEffect(() => 
   if(errorMessage)  // Add an existential condition so that useEffect doesn't run for empty message on first rendering
       setTimeout(() => 
          setErrorMessage('');
       , 5000);
   

, [isChanged.current]); // Now the mutation will not run unless a re-render happens but setErrorMessage does create a re-render

const addErrorMessage = (msg) => 
  setErrorMessage(msg);
  isChanged.current = !isChanged.current; // intentionally trigger a change

上面的示例考虑了这样一个事实,即您可能也想从其他地方设置 errorMessage,而您不想重置它。但是,如果您想在每次 setErrorMessage 时重置消息,您可以简单地编写一个普通的 useEffect 像

useEffect(() => 
    if(errorMessage !== "") // This check is very important, without it there will be an infinite loop
        setTimeout(() => 
              setErrorMessage('');
         , 5000);
    

, [errorMessage]) 

【讨论】:

是的,谢谢。我自己找到了 if (successfullyCreatedCard !== ) 的解决方案。但是 useRef 听起来很有趣。我还没有完全理解它,但我会学习它。谢谢你。

以上是关于在功能组件中使用回调对 setState 进行反应的主要内容,如果未能解决你的问题,请参考以下文章

反应 setState 嵌套数组回调

反应功能组件未从父组件更新 setState

更新后如何将函数传递给 SetState 回调? (反应)

React:如何使用功能性 usestate/useEffect 复制特定的组件类 setstate 回调示例?

无法在反应组件中使用 setState

状态未使用setState进行更新反应