在功能组件中通过回调来响应setState

时间:2020-05-16 17:23:12

标签: reactjs react-hooks react-functional-component use-state

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

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

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

我想知道是否可以使用useState挂钩在功能组件内完成此操作。

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

enter image description here

所以我想-此功能未包含在功能组件中吗?

1 个答案:

答案 0 :(得分:3)

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])