【问题标题】:Conditional rendering not working after a timeout delay in ReactJS在 ReactJS 中超时延迟后条件渲染不起作用
【发布时间】:2020-07-03 22:54:57
【问题描述】:

我正在使用 ReactJS(使用 Gatsby 框架)构建一个简单的网站,并尝试使用状态和 React 钩子处理一些条件渲染。我想要完成的是基本上有一个欢迎消息显示 4 秒,然后呈现不同的内容。

这是渲染状态更改的代码(注意:有两种不同的 newGame 状态,因为一个在用户第一次看到此屏幕时渲染,另一个在用户通过 cookie 返回站点时渲染)。

useEffect(() => {
  if ((welcomeScreen === true && phase === 'newGame') || (welcomeScreen === true && phase === 'newGamePlus')) {
    const timer = setTimeout(() => {    
    setPhase('gameStart');
    setWelcomeStatus(false);
  }, 4000);
  return () => clearTimeout(timer);
  }
 }, [phase, welcomeScreen]);

这是我的状态管理链。这可能非常不正统/笨拙,因为我对此很陌生,所以请随时纠正我的错误或引导我走向更好的道路。

if (phase === 'index') {
  return (
    <Layout>
    <div className="mainContainer">
    <h1>Enter your name~</h1>
        <form onSubmit={handleClick}>
          <input
            className="nameInput"
            onChange={handleChange}
            type="text"
            placeholder="What's your name?"
            value={name}
          />
          <button type="submit" className="nameButton">Submit</button>
          { showErrorMessage ? <ErrorText /> : null }
        </form>
      </div>
    </Layout>
  )
  } else if (phase === 'newGamePlus' && welcomeScreen === true) {
  return (
    <Layout>
    <div className="mainContainer">
    <h1>Welcome back, {cookies.get('userName')}~</h1>
      </div>
    </Layout>
  ) }
  else if (phase === 'newGame' && welcomeScreen === true) {
    return (
      <Layout>
      <div className="mainContainer">
      <h1>Welcome, {savedName}~</h1>
        </div>
      </Layout>
    )
    } else if (phase === 'gameStart' && welcomeScreen === false) {
      return (
        <Layout>
        <div className="mainContainer">
        <h1>Time to play!</h1>
        </div>
        </Layout>
      )
    };

预期的效果是让欢迎屏幕显示最终“游戏开始”阶段的内容。目前,有 4 秒的延迟,然后站点崩溃,并显示来自 React 的“无渲染”错误消息。我非常感谢您能深入了解我在这里做错了什么,我敢肯定这可能是多方面的!

谢谢!

【问题讨论】:

    标签: reactjs gatsby


    【解决方案1】:

    使用 setTimeout() 时,状态更新不是批处理。在您的代码中, setPhase('gameStart') 将触发状态更改,因此将再次执行 useEffect 并跳过 setWelcomeStatus(false)。您将始终以 phase === 'gameStart' && welcomeScreen === true结束。

    可能的解决方案: 在useEffect中只使用了一个setState,所以需要将变量phase和welcomeScreen改为一个对象变量,而不是两个单独的变量。

    【讨论】:

    • 嗨,我尝试做一些事情来达到这个效果,但它产生了同样的问题。您能否详细说明您的解决方案? useEffect(() =&gt; { if ((phases.welcomeScreen === true &amp;&amp; phase === 'newGame') || (phases.welcomeScreen === true &amp;&amp; phase === 'newGamePlus')) { const timer = setTimeout(() =&gt; { setPhase('gameStart'); }, 4000); return () =&gt; clearTimeout(timer); } }, [phase, phases.welcomeScreen]);
    猜你喜欢
    • 1970-01-01
    • 2021-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-04
    • 1970-01-01
    • 1970-01-01
    • 2022-09-27
    相关资源
    最近更新 更多