Why is this duplicating in the console? I noticed this while working on another projects and noticed the amount of HTML elements I was adding using jQuery was twice as much as expected (building a notification framework). I tried recreating the problem in a new project and the behavior persisted
DupeMountTest.js:
import React, {Component, useEffect} from "react";
const DupeMountTest = () => {
useEffect(() => {
console.log("useEffect")
}, [])
return (
<div>
<p>Test</p>
</div>
)
}
export default DupeMountTest
App.js:
import {
BrowserRouter as Router,
Route, Routes,
} from "react-router-dom";
import DupeMountTest from "./DupeMountTest";
function App() {
return (
<Router>
<div className="App">
<Routes>
<Route path={"/"} exact element={<DupeMountTest/>}/>
</Routes>
</div>
</Router>
);
}
export default App
index.js:
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
Console:
I also attempted this using a class component but "Mounted" also logged twice.
DupeMountTest using class component:
import React, {Component, useEffect} from "react";
class DupeMountTest extends Component {
componentDidMount() {
console.log("Mounted")
}
render() {
return (
<div>
<p>Test</p>
</div>
)
}
}
export default DupeMountTest
CodePudding user response:
Answer provided by evolutionxbox inside the comments section. Problem solved by removing <React.StrictMode>
in index.js
:
Updated index.js:
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
// <React.StrictMode>
//
// </React.StrictMode>
<App />
);
CodePudding user response:
React 18 introduces a new development-only check to Strict Mode. This new check will automatically unmount and remount every component, whenever a component mounts for the first time, restoring the previous state on the second mount.
https://reactjs.org/blog/2022/03/29/react-v18.html#new-strict-mode-behaviors
So, your useEffect
is running twice on each mount.
This was put in place to lay the groundwork for future features, so it's not exactly a bad thing.
In the future, we’d like to add a feature that allows React to add and remove sections of the UI while preserving state. For example, when a user tabs away from a screen and back, React should be able to immediately show the previous screen. To do this, React would unmount and remount trees using the same component state as before.
This feature will give React apps better performance out-of-the-box, but requires components to be resilient to effects being mounted and destroyed multiple times. Most effects will work without any changes, but some effects assume they are only mounted or destroyed once.
It's also discussed in this post (thanks @evolutionxbox):
I really liked a comment there that basically summed up the answer to what you're wondering about:
"it's a feature, not a bug."