score:263
Put the console.log inside the useEffect
Probably you have other side effects that cause the component to rerender but the useEffect itself will only be called once. You can see this for sure with the following code.
useEffect(()=>{
/*
Query logic
*/
console.log('i fire once');
},[]);
If the log "i fire once" is triggered more than once it means your issue is one of 3 things.
This component appears more than once in your page
This one should be obvious, your component is in the page a couple of times and each one will mount and run the useEffect
Something higher up the tree is unmounting and remounting
The component is being forced to unmount and remount on its initial render. This could be something like a "key" change happening higher up the tree. you need to go up each level with this useEffect until it renders only once. then you should be able to find the cause or the remount.
React.Strict mode is on
StrictMode renders components twice (on dev but not production) in order to detect any problems with your code and warn you about them (which can be quite useful).
This answer was pointed out by @johnhendirx and written by @rangfu, see link and give him some love if this was your problem.
score:1
I've had this issue where something like:
const [onChainNFTs, setOnChainNFTs] = useState([]);
would trigger this useEffect twice:
useEffect(() => {
console.log('do something as initial state of onChainNFTs changed'); // triggered 2 times
}, [onChainNFTs]);
I confirmed that the component MOUNTED ONLY ONCE and setOnChainNFTs was NOT called more than once - so this was not the issue.
I fixed it by converting the initial state of onChainNFTs to null
and doing a null check.
e.g.
const [onChainNFTs, setOnChainNFTs] = useState(null);
useEffect(() => {
if (onChainNFTs !== null) {
console.log('do something as initial state of onChainNFTs changed'); // triggered 1 time!
}
}, [onChainNFTs]);
score:1
Here is the custom hook for your purpose. It might help in your case.
import {
useRef,
EffectCallback,
DependencyList,
useEffect
} from 'react';
/**
*
* @param effect
* @param dependencies
* @description Hook to prevent running the useEffect on the first render
*
*/
export default function useNoInitialEffect(
effect: EffectCallback,
dependancies?: DependencyList
) {
//Preserving the true by default as initial render cycle
const initialRender = useRef(true);
useEffect(() => {
let effectReturns: void | (() => void) = () => {};
/**
* Updating the ref to false on the first render, causing
* subsequent render to execute the effect
*
*/
if (initialRender.current) {
initialRender.current = false;
} else {
effectReturns = effect();
}
/**
* Preserving and allowing the Destructor returned by the effect
* to execute on component unmount and perform cleanup if
* required.
*
*/
if (effectReturns && typeof effectReturns === 'function') {
return effectReturns;
}
return undefined;
}, dependancies);
}
score:2
Not sure why you won't put the result in state, here is an example that calls the effect once so you must have done something in code not posted that makes it render again:
const App = () => {
const [isLoading, setLoad] = React.useState(true)
const [data, setData] = React.useState([])
React.useEffect(() => {
console.log('in effect')
fetch('https://jsonplaceholder.typicode.com/todos')
.then(result => result.json())
.then(data => {
setLoad(false)//causes re render
setData(data)//causes re render
})
},[])
//first log in console, effect happens after render
console.log('rendering:', data.length, isLoading)
return <pre>{JSON.stringify(data, undefined, 2)}</pre>
}
//render app
ReactDOM.render(<App />, document.getElementById('root'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="root"></div>
To prevent the extra render you can combine data and loading in one state:
const useIsMounted = () => {
const isMounted = React.useRef(false);
React.useEffect(() => {
isMounted.current = true;
return () => isMounted.current = false;
}, []);
return isMounted;
};
const App = () => {
const [result, setResult] = React.useState({
loading: true,
data: []
})
const isMounted = useIsMounted();
React.useEffect(() => {
console.log('in effect')
fetch('https://jsonplaceholder.typicode.com/todos')
.then(result => result.json())
.then(data => {
//before setting state in async function you should
// alsways check if the component is still mounted or
// react will spit out warnings
isMounted.current && setResult({ loading: false, data })
})
},[isMounted])
console.log(
'rendering:',
result.data.length,
result.loading
)
return (
<pre>{JSON.stringify(result.data, undefined, 2)}</pre>
)
}
//render app
ReactDOM.render(<App />, document.getElementById('root'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="root"></div>
score:2
It is the feature of ReactJS while we use React.StrictMode. StrictMode activates additional checks and warnings for its descendants nodes. Because app should not crash in case of any bad practice in code. We can say StrictMode is a safety check to verify the component twice to detect an error.
You will get this <React.StricyMode> at root of the component.
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
if you want to restrict components to render twice, You can remove <React.StrictMode>
and check it. But It is necessary to use StrictMode
to detect a run time error in case of bad code practice.
score:4
I'm using this as my alternative useFocusEffect
. I used nested react navigation stacks like tabs and drawers and refactoring using useEffect
doesn't work on me as expected.
import React, { useEffect, useState } from 'react'
import { useFocusEffect } from '@react-navigation/native'
const app = () = {
const [isloaded, setLoaded] = useState(false)
useFocusEffect(() => {
if (!isloaded) {
console.log('This should called once')
setLoaded(true)
}
return () => {}
}, [])
}
Also, there's an instance that you navigating twice on the screen.
score:7
Please check your index.js
<React.StrictMode>
<App />
</React.StrictMode>
Remove the <React.StrictMode> wrapper you should now fire once
root.render(
<App />
);
score:16
Remove <React.StrictMode> from index.js This code will be
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
this
root.render(
<App />
);
React StrictMode renders components twice on dev server
score:27
You are most likely checking the issue on a dev environment with strict mode enabled. To validate this is the case, search for <React.StrictMode> tag and remove it, or build for production. The double render issue should be gone. From React official documentation
Strict mode can’t automatically detect side effects for you, but it can help you spot them by making them a little more deterministic. This is done by intentionally double-invoking the following functions:
- Functions passed to useState, useMemo, or useReducer
- [...]
Similar question here My React Component is rendering twice because of Strict Mode
Source: stackoverflow.com
Related Query
- React Hooks: useEffect() is called twice even if an empty array is used as an argument
- React Hooks - 0 vs. empty array as second argument in useEffect
- How This React Hook i.e useEffect is re-rendering even if the second argument being passed is an empty array
- React Hooks - useEffect fires even though the state did not change
- useEffect getting called twice in react v18
- React Hook useEffect has a missing dependency when passing empty array as second argument
- How do I correctly add data from multiple endpoints called inside useEffect to the state object using React Hooks and Context API?
- React hooks useEffect running even with [] given as deps
- React Hooks - useState initializes empty array that becomes object?
- State returns an empty array even after setting in useEffect
- why does useEffect run once the window.innerWidth changes even though the second param in it is an empty array
- React Hooks & UseEffect not updating display with socketIO data. Only renders elements in array
- React useEffect returns empty array after fetching data with axios
- React Hooks useState Array empty with states rendered in the component
- useEffect of react hooks throwing an error when used inside axios
- React useState item seems to be empty when called even though item is set
- React Hooks: State is resetting to empty array even if I use the spread operator, prevState, etc
- update array of objects using useEffect in React Hooks
- Why my react app rendered twice and give me an empty array in first render when I'm trying fetching API?
- mapStateToprops is getting called twice and returning an empty array at the end
- useEffect getting called twice React JS
- React Hooks useEffect saves the last state and won't update it with the new one. It runs twice with two different states
- React useEffect infinite loop despite empty array
- React UseEffect function triggering in empty array change
- React hooks -to reinitialise array to empty
- Correct dependency array for useEffect with React hooks
- Update 2d array using React and hooks useState and useEffect
- Empty Array is being returned before PromiseAll is resolved when used in useEffect method
- Reack Hook: useEffect() is called twice firt witha n empty array and then with the vales from the database
- React Hooks changing state of an array inside of asycn function after useEffect call
More Query from same tag
- How do I obtain all the information of the object of the "activeCat" that holds the state?
- reactjs react router picking up changes in the url
- React & Babel: You may need an additional loader to handle the results of these loaders
- How can I fill review icons depending on average rating?
- How to add attribute name and attribute value dynamically in React
- Conditionally render <td> in a React component
- React handleOnSubmit() need to be clicked twice
- Inserting JSON File Data into React Bootstrap Table 2
- Export two excel data into single excel sheet by adding heading and some calculated data
- Implement react-bootstrap custom dropdown example in Typescript
- Typescript errors and says it can't find modules for imports on assets such as images
- Don't let flex to wrap label text of toggle
- After submit the form how do I redirect to welcome component in React
- Error with React render
- Toggle columns on react-bootstrap-table2
- Using custom class as ItemsControl Tag in WPF XAML?
- Reactjs - what is the workflow to force a refresh?
- State of react app is not current with what I have in my database?
- How to upload multiple files with Filestack?
- React router `this.props.history.push` - history not defined
- useEffect to make event handler for own defined event
- React TypeError: React.renderComponent is not a function
- How to sort the table by date if the date is not filled everywhere?
- Working with Audio objects in React/ Redux
- How to view client markup to debug checksum errors in react
- ReactJS: useEffect is not run when the url changes
- Is there a way to check for any state changes made by a user in React?
- Loading Div before render Page (React)
- Why WhatsApp web does not show og image?
- How to understand complicated typescript generic types?