React函数组件未修改refreshpage却触发componentDidUpdate效果问题
React中未修改依赖项却触发模拟componentDidUpdate的useEffect
代码示例
import { useState, useEffect } from 'react'; function ManageUsers(){ const [refreshpage, setrefreshpage] = useState(0); const handerefreshpage = () => { console.log(refreshpage); setrefreshpage(refreshpage + 1); } useEffect(() => { // 模拟componentDidMount console.log('ManageUsers run useEffect --> componentDidMount'); }, []); useEffect(() => { // 本意是模拟componentDidUpdate,仅在refreshpage变化时触发 console.log('ManageUsers run useEffect --> componentDidUpdate'); }, [refreshpage]); return( // 组件内容省略 ) } export default ManageUsers;
问题现象
运行应用时,明明没有修改过refreshpage的值,模拟componentDidUpdate的第二个useEffect却被触发了,控制台同时打印出了componentDidMount和componentDidUpdate的日志。
原因分析
这是React的设计逻辑:带依赖项的useEffect在组件首次渲染时也会执行一次,和类组件的componentDidUpdate不一样——componentDidUpdate仅在组件更新阶段触发,首次渲染不会执行。你这里的第二个useEffect虽然依赖了refreshpage,但首次渲染时它还是会跑一遍,并不是只有refreshpage变化时才执行。
解决方案
如果要严格模拟componentDidUpdate的行为(即首次渲染不执行,仅依赖项变化时执行),可以用useRef存储一个“是否首次渲染”的标记,在useEffect里做判断:
import { useState, useEffect, useRef } from 'react'; function ManageUsers(){ const [refreshpage, setrefreshpage] = useState(0); const isFirstRender = useRef(true); // 标记是否为首次渲染 const handerefreshpage = () => { console.log(refreshpage); setrefreshpage(refreshpage + 1); } useEffect(() => { console.log('ManageUsers run useEffect --> componentDidMount'); }, []); useEffect(() => { // 首次渲染时直接返回,不执行后续逻辑 if (isFirstRender.current) { isFirstRender.current = false; return; } // 这里才是真正的componentDidUpdate逻辑 console.log('ManageUsers run useEffect --> componentDidUpdate'); }, [refreshpage]); return( // 组件内容 ) } export default ManageUsers;
这样修改后,第二个useEffect就只会在refreshpage变化时执行,和componentDidUpdate的行为一致了。
内容的提问来源于stack exchange,提问作者Single.Traveler
相关产品推荐
相关产品推荐

