I’m using multiple useEffect
hooks to perform the componentDidMount
and componentDidUpdate
functionalities, however, looks like when component loads, all my useEffect fires initially…
const testComp = () => { const stateUserId = useSelector(state => { return state.userId; }); const [userId, setUserId] = useState(stateUserId); const [active, setActive] = useState(false); const [accountId, setAccountId] = useState(); useEffect(() => { console.log('component did mount...'); }, [userId]); useEffect(() => { console.log('should trigger when userId changes...'); }, [userId]); useEffect(() => { console.log('should trigger when active changes...'); }, [active]); useEffect(() => { console.log('should trigger when accountId changes...'); }, [accounted]); return (<div>...</div); }
when my component mounts, I see all those console log there
component did mount... should trigger when userId changes... should trigger when active changes... should trigger when accountId changes...
How could I only let my first useEffect
fires, but the other three fires when the dependency changes only?
Advertisement
Answer
useEffect
is not a direct replacement of componentDidMount
and componentDidUpdate
. Effect will run after each render, which is why you are seeing all those console logs. According to the React documentation, the second parameter of useEffect
means
you can choose to fire them (effects) only when certain values have changed.
After the initial render, if the component is rendered again, only effects watch the corresponding value changes are triggered.
One way to achieve what you want is by creating additional variables to host initial values and do comparisons in the useEffect
when you need to.
const testComp = () => { const initUserId = useSelector(state => { return state.userId; }); const stateUserId = initUserId; const [userId, setUserId] = useState(stateUserId); useEffect(() => { console.log('component did mount...'); }, [userId]); useEffect(() => { if (userId !== initUserId) { console.log('should trigger when userId changes...'); } }, [userId]); return <div>...</div> }