0

我创建了一个演示。

演示网址:https ://4ikgc.csb.app/

为什么 outerHTML 总是<h1>abc</h1>

顺便说一句,为什么控制台似乎将所有内容记录了两次。

现在console.log的内容是:

render h1: {current: null} undefined
render h1: {current: null} undefined
second abc <h1>abc</h1>
forth abc <h1>abc</h1>
first abc <h1>abc</h1>
first abc <h1>abc</h1>
third hello1 <h1>abc</h1>
third hello1 <h1>abc</h1>
fifth hello2 <h1>abc</h1>
fifth hello2 <h1>abc</h1>
render h1: <h1>​hello3​&lt;/h1>​ <h1>abc</h1>
render h1: <h1>​hello3​&lt;/h1>​ <h1>abc</h1>

但我认为正确的内容是:

render h1: {current: null} undefined
second abc <h1>abc</h1>
forth abc <h1>abc</h1>
first abc <h1>abc</h1>
third hello1 <h1>abc</h1>
fifth hello2 <h1>abc</h1>
render h1: <h1>​hello3​&lt;/h1>​ <h1>hello3</h1>

希望有人可以帮助我!非常感谢!

import React from "react";

class Hello extends React.Component {
  constructor(props) {
    super(props);
    this.h1 = React.createRef();
    this.state = {
      name: "abc"
    };
  }
  componentDidMount() {
    this.setState((state, props) => {
      console.log("first", state.name, this.h1.outerHTML);
      return {
        name: "hello1"
      };
    });
    console.log("second", this.state.name, this.h1.outerHTML);
    this.setState((state, props) => {
      console.log("third", state.name, this.h1.outerHTML);
      return {
        name: "hello2"
      };
    });
    console.log("forth", this.state.name, this.h1.outerHTML);
    this.setState((state, props) => {
      console.log("fifth", state.name, this.h1.outerHTML);
      return {
        name: "hello3"
      };
    });
  }
  render() {
    console.log("render h1:", this.h1, this.h1.outerHTML);

    return <h1 ref={ref => (this.h1 = ref)}>{this.state.name}</h1>;
  }
}

export default Hello;

4

1 回答 1

1

您的 Hello 组件有一个H1,而您使用该Hello组件的位置也有另一个H1

    <div className="App">
      <Hello />
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
    </div>

你得到 2 的原因console.logs是反应生命周期是如何工作的。您的第一次console.log发生render在组件最初被渲染时。组件渲染后,反应触发componentDidUpdate生命周期方法。

然后,当您this.setState在该方法中触发 a 时,它会再次触发重新渲染render。那是你的第二个console.log。还因为在您的特定情况下,您在其中设置this.state多次componentDidUpdate会触发多个状态更改。

另请注意,在development模式下使用 react strict<React.StrictMode>时,setState会调用两次。这是故意的。它不会在生产中发生。

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  rootElement
);

参考:
https ://github.com/facebook/react/issues/12856#issuecomment-390206425

https://reactjs.org/docs/strict-mode.html#detecting-unexpected-side-effects

于 2020-05-01T14:18:48.197 回答