即使状态更改后,如何使用componentDidMount?

时间:2020-03-25 19:33:44

标签: reactjs

我正在学习React并遇到以下代码:

class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date()};
  }

  componentDidMount() {
    this.timerID = setInterval(
      () => this.tick(),
      1000
    );
  }

  componentWillUnmount() {
    clearInterval(this.timerID);
  }

  tick() {
    this.setState({
      date: new Date()
    });
  }

  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

问题是,即使状态更改后,即如何调用componentDidMount,即

componentDidMount() {
        this.timerID = setInterval(
          () => this.tick(),
          1000
        );
      }
调用代码setInterval上方的

,该代码依次调用更改状态的tick函数。但是在状态更改后以及组件重新呈现之后,是否再次调用componentDidMount?

3 个答案:

答案 0 :(得分:1)

再次调用componentDidMount吗?

不,不会再次调用。在组件渲染componentDidMount中,仅在第一个渲染上调用 。如果您需要再次获取先前的值,则可以为此componentDidUpdate使用另一种生命周期方法。像这样:

componentDidUpdate(prevProps, prevState){
    console.log(prevState);
}

答案 1 :(得分:1)

没错,componentDidMount在渲染后仅被调用一次,而tick函数在每一秒后又被调用一次。让我详细说明:

渲染后->

  1. componentDidMount被调用。在其中setInterval被调用。
  2. setInterval在事件队列中排队,向this.timerID返回一个id(数字),并且componentDidMount退出。
  3. tick函数被压入堆栈并在一秒钟后执行。
  4. 因为它是setInterval,所以它在队列中,一秒钟后再次执行。
  5. 遵循模式...

我了解到您对于如何一次又一次地调用tick而不是componentDidMount感到困惑。请参阅以下内容:

fuction parentFunction() {
  setInterval(() => {
    childFunction();
  }, 1000);
}

parentFunction();

在这种情况下,childFunction位于setInterval内部(不是parentFunction),因此仅一次childFunction被调用,而不是{{ 1}}。

希望它会有所帮助:)

答案 2 :(得分:0)

组件将在首次渲染,卸载后或更改关键道具时安装。

因此,如果您有一个名为WillSometimesRender的组件,它将在以前渲染但现在不渲染时卸载。

如果您有一个名为KeyChange的组件,则使用其他键进行渲染时将其卸载,然后重新安装(请参见下面的代码)

class KeyChange extends React.Component {
  componentDidMount() {
    console.log('key change got mounted');
  }
  componentWillUnmount() {
    console.log('key change got unmounted');
  }
  render() {
    return <div>key change</div>;
  }
}
class WillSometimesRender extends React.Component {
  componentDidMount() {
    console.log('will sometimes render got mounted');
  }
  componentWillUnmount() {
    console.log('will sometimes render got unmounted');
  }
  render() {
    return <div>will sometimes render</div>;
  }
}
const App = () => {
  const [key, setKey] = React.useState(1);
  return (
    <div>
      <button onClick={() => setKey(key => key + 1)}>
        Change key
      </button>
      <KeyChange key={key} />
      {key % 2 && <WillSometimesRender />}
    </div>
  );
};

ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="root"></div>