首页 > 解决方案 > 在嵌套的 setTimeout 回调中更新 React 状态

问题描述

有人可以告诉我这有什么问题以及为什么“视频变量”的状态仍然为假吗?那么,即使在 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>
  );
}

标签: reactjsreact-hooksstate

解决方案


当您调用 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>
  </>
);

}


推荐阅读