简体   繁体   中英

React - Strict Mode off, functional component constructed second time after first state change only

I'm confused why function components (non class components don't confuse with functional) are constructed twice when state changes?

My understanding was that the function is constructed once just like a class' component constructor?

Note: React is NOT running in strict mode.

Codesandbox

Sample code:

index.js:

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, // notice no strict mode
  rootElement
);

Eg 1: LogStatement called once - simple and obvious:

function App1() {
  console.log("App constructed");
  return <div>Hello</div>;
}

Eg 2: LogStatement called twice - not quite obvious but maybe its due to setDidMount? :

function App2() {
  console.log("App constructed");
  const [didMount, setDidMount] = useState(false);

  useEffect(() => {
    setDidMount(true);
  }, []);

  return <div>Hello</div>;
}

Eg 3: LogStatement called twice. no matter how many independent state variables:

function App3() {
  console.log("App constructed:" + i++);

  const [didMount, setDidMount] = useState(false);
  const [someState, setSomeState] = useState("empty");

  useEffect(() => {
    setDidMount(true);
  }, []);

  useEffect(() => {
    setSomeState("full");
  }, []);

  return <div>Hello</div>;
}

Finally class component

Eg 4: LogStatement called once - as expected

class App4 extends Component {
  constructor() {
    super();
    this.state = {
      didMount: false
    };
    console.log("App constructed:" + i++);
  }

  componentDidMount() {
    this.setState({
      didMount: true
    });
  }

  render() {
     return <div>Hello</div>;
  }
}

My understanding was that the function is constructed once just like a class' component constructor?

It's not constructed at all, that's just a class thing. Putting a log statement in the body of a function component is roughly equivalent to putting it in the render method of a class component. So your log is telling you how many times the component rendered. Setting state causes rendering (usually), so by calling setDidMount(true) , you are rerendering the component.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM