Reputation: 1177
I just started a new create-react-app project and noticed that react is rendering components twice! My react version in package.json is "react": "^16.13.1"
import React, { useRef } from "react";
const App = () => {
const renders = useRef(0);
console.log("renders: ", renders.current++);
return (
<div>
Hello
</div>
);
};
This produces on first render:
renders: 0
renders: 0
Now if I add a button to increment state, each state change also produces two additional renders:
import React, { useRef } from "react";
const App = () => {
const [count, setCount] = useState(0);
const renders = useRef(0);
console.log("renders: ", renders.current++);
return (
<div>
<button onClick={() => setCount(count + 1)}>increment</button>
<div>count: {count}</div>
</div>
);
};
This will result in:
//--- initial render
renders: 0
renders: 0
//--- first click
renders: 1
renders: 2
//--- second click
renders: 3
renders: 4
//--- third click
renders: 5
renders: 6
Is this normal or is this a bug in the latest version of react?
Upvotes: 5
Views: 5674
Reputation: 345
In addition to the StrictMode issue you found, I think when you're using a ref
like that it creates a side-effect so you'd typically need to put it in useEffect
to prevent it from rendering twice:
import React, { useState, useEffect, useRef } from "react";
const App = () => {
const [count, setCount] = useState(0);
const renders = useRef(0);
useEffect(() => {
// Every time the component has been re-rendered,
// the counter is incremented
console.log("renders: ", renders.current++);
});
return (
<div>
<button onClick={() => setCount(count + 1)}>increment</button>
<div>count: {count}</div>
</div>
);
};
export default App;
Upvotes: 2
Reputation: 1177
OK looks like I found out the reason. After inspecting index.js
I found the following:
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
Looks like create-react-app now includes React.StrictMode
which double invokes certain methods in development mode (not in production).
Upvotes: 13