反应dom externalHTML似乎不对吗?

时间:2020-05-01 12:00:18

标签: reactjs innerhtml react-dom react-ref outerhtml

I have created a demo.

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

为什么externalHTML始终为<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​</h1>​ <h1>abc</h1>
render h1: <h1>​hello3​</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​</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;

1 个答案:

答案 0 :(得分: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时,它将再次触发render的重新渲染。这是您的第二个console.log。另外,由于在您的特定情况下,您在this.state中多次设置了componentDidUpdate,因此会触发多个状态更改。

还要注意,在development模式下并使用反应严格的<React.StrictMode>时,setState被调用两次。这是故意的。它不会在生产中发生。

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

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

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