Cristian E.
Cristian E.

Reputation: 3583

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>;
  }
}

Upvotes: 0

Views: 1167

Answers (1)

Nicholas Tower
Nicholas Tower

Reputation: 84982

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.

Upvotes: 1

Related Questions