【问题标题】:Updating React state in nested setTimeout callbacks在嵌套的 setTimeout 回调中更新 React 状态
【发布时间】:2021-04-14 22:34:21
【问题描述】:

谁能告诉我这有什么问题以及为什么“视频变量”的状态仍然为假?所以,即使在 h2 元素已经渲染并且可见(即视频变量的状态已更新为 true)之后,当我单击并调用 hideVideo 函数时,视频状态仍然为 false?非常感谢。

export default function App() {
  const [message, showMessage] = useState(false);
  const [video, setVideo] = useState(false);
  
let modalTimeout, videoTimeout;

  useEffect(() => {
   
    window.addEventListener("click", hideVideo);
    setupTimeouts();
    return () => {
      clearTimeout(modalTimeout);
      clearTimeout(videoTimeout);
    };
  }, []);

  const setupTimeouts = () => {
    modalTimeout = setTimeout(() => {
      showMessage(true);

      videoTimeout = setTimeout(() => {
       
        showMessage(false);
        setVideo(true);
      }, 4000);
    }, 2000);
  };

  const hideVideo = () => {
    console.log(video);
    showMessage(false);
    if (video === true) {
      setVideo(false);
      
    }
  };

  return (
    <div className="App">
      {message && <h1>Message</h1>}
      {video && <h2>Video</h2>}
    </div>
  );
}

【问题讨论】:

    标签: reactjs react-hooks state


    【解决方案1】:

    当您调用 useEffect 时,窗口侦听器会将默认的视频值附加到函数 hideVideo(),因此它将始终为假,我创建了一个按钮来向您显示视频状态值确实发生了变化。检查最后一个测试函数

    export default function App() {
    const [message, showMessage] = useState(false);
    const [video, setVideo] = useState(false);
    let modalTimeout, videoTimeout;
    
    useEffect(() => {
      window.addEventListener("click", hideVideo);
      setupTimeouts();
      return () => {
        clearTimeout(modalTimeout);
        clearTimeout(videoTimeout);
      };
      }, []);
    
    const setupTimeouts = () => {
      modalTimeout = setTimeout(() => {
        showMessage(true);
        videoTimeout = setTimeout(() => {
          showMessage(false);
          setVideo(true);
        }, 4000);
      }, 2000);
    };
    
    const hideVideo = () => {
      console.log(video);
      showMessage(false);
      if (video) {
        setVideo(false);
      }
    };
    const test = (event) => {
      event.stopPropagation();
      console.log(video)
    }
    return (
      <>
        {message && <h1>Message</h1>}
        {video && <h2>Video</h2>}
        <button onClick={test}>test</button>
      </>
    );
    

    }

    【讨论】:

    • 谢谢加布里埃尔·埃斯皮诺萨。到目前为止,我一直在使用类组件,从未遇到过这个问题。显然,使用钩子,事件处理程序无法访问状态。
    猜你喜欢
    • 1970-01-01
    • 2017-08-08
    • 2020-11-13
    • 1970-01-01
    • 2017-08-19
    • 2019-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多