React函数组件中使用带有回调的setState

3

我有一个非常简单的示例,我在类组件中编写:

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

因此,在这里我调用了 setState() 方法,并给它传递了一个回调函数作为第二个参数。

我想知道是否可以在使用 useState hook 的函数组件中实现这个功能。

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

enter image description here

所以我猜测,这个功能不能被包含在函数组件中?

1个回答

4

在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,但您不想重置它。然而,如果您想每次设置错误消息时重置消息,您可以简单地编写一个常规的useEffect,例如:
useEffect(() => {
    if(errorMessage !== ""){ // This check is very important, without it there will be an infinite loop
        setTimeout(() => {
              setErrorMessage('');
         }, 5000);
    }

}, [errorMessage]) 

1
是的,谢谢。我自己找到了解决方案,使用 if (successfullyCreatedCard !== {})。但是 useRef 的东西听起来很有趣。我还没有完全理解它,但我会学习的。谢谢。 - Slowwie
您的回答效果很好,但如果有五个回调函数,我需要创建五个单独的引用和 useEffect 钩子吗?有没有更高效的方法来解决这个问题? - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接