【问题标题】:React: setState with Countdown反应:带倒计时的 setState
【发布时间】:2024-04-18 02:35:02
【问题描述】:

我的主 App.js 类中有一个状态计数器。我还有一个 Countdown.js,每次他完成时都会更新他父类的计数器。但是当计时器完成一次时,我得到一个错误。此外,状态计数器从 0 跳到 2,而不是从 0 跳到 1...

Warning: Cannot update during an existing state transition (such as within `render`).

我怎样才能摆脱这个错误?或者你有一个解决方案如何计数++,当计时器完成时?

我的班级 App.js:

import React from "react"
import "./App.css"
import Countdown from "./Countdown.js"

class App extends React.Component {
  constructor() {
    super();
    this.state = {
      counter: 0
    };
    this.count = this.count.bind(this);
  }

  count() {
    this.setState(prevState => ({
      count: prevState.counter++
    }));
  }

  render() {
    return (
      <div className="window">
        <p>{this.state.counter}</p>
        <Countdown count={this.count} />
      </div>
    );
  }
}

export default App

我的倒计时.js

import React from "react";
import CountDown from "react-countdown";

class CountdownQuestion extends React.Component {
  constructor() {
    super();
    this.state = {
      time: 3000
    };
  }

  render() {
    const renderer = ({ seconds, completed }) => {
      if (completed) {
        this.props.count();
        return <h2>Zeit abgelaufen</h2>;
      } else {
        return <h3>{seconds}</h3>;
      }
    };

    return (
      <CountDown date={Date.now() + this.state.time} renderer={renderer} />
    );
  }
}

export default CountdownQuestion;

【问题讨论】:

    标签: reactjs state countdown setstate


    【解决方案1】:

    嗯,就像错误所说的那样。您无法在渲染期间更新状态(例如在 count() 函数中)。您可能最好使用onComplete 钩子。

    class CountdownQuestion extends React.Component {
      constructor() {
        super();
        this.state = {
          time: 3000
        };
      }
    
      render() {
        // Removing this.props.count() from this function also keeps it more clean and focussed on the rendering.
        const renderer = ({ seconds, completed }) => {
          if (completed) {
            return <h2>Zeit abgelaufen</h2>;
          } else {
            return <h3>{seconds}</h3>;
          }
        };
    
        return (
          <CountDown
            date={Date.now() + this.state.time}
            onComplete={this.props.count} // <-- This will trigger the count function when the countdown completes.
            renderer={renderer}
          />
        );
      }
    }
    

    【讨论】:

    • 感谢您的回答!现在错误消失了,但不幸的是它只计数到 1 然后停止。为什么不计算更多?它应该,因为当我改变状态时,它也应该重新渲染倒计时
    • &lt;Countdown /&gt; 不会重新启动,因为它在第一次之后已经挂载。在&lt;App /&gt; 中,您可以将key={this.state.counter} 添加到&lt;CountDown /&gt; 以实际重新安装它。或者您可以向倒计时组件添加 ref 并使用 onComplete 来重新启动它,例如onComplete = () =&gt; { this.props.count(); this.countdownRef.current.start();};
    • 衷心感谢您,您真是太棒了!现在一切正常。