useEffect调用Redux函数报依赖缺失警告 方案对比及Redux Hooks迁移问题咨询
方案对比与问题修正
方案优先级排序
- Redux Hooks方案最优:这是Redux官方当前首推的用法,代码更简洁,没有高阶组件的嵌套层级,
useDispatch返回的引用天生稳定,直接加到useEffect依赖数组中不会触发重复执行,完全解决依赖警告问题,也不需要额外写useCallback做冗余的引用稳定处理。 - connect+useCallback方案其次:虽然可以解决警告,但属于过渡性的绕路写法,需要额外维护
useCallback的依赖,代码冗余度更高,没有必要。 - 忽略依赖警告/硬加props.action到依赖最不可取:前者属于不符合React Hook规则的写法,未来可能出现不可预期的渲染问题;后者因为
connect注入的action引用不稳定,大概率会出现重复触发请求的问题。
你的迁移代码存在的问题
- 缺少必要导入:未从
react-redux导入useDispatch、useSelector,还保留了无用的connect导入 - 未声明
dispatch变量:组件内没有调用useDispatch()获取dispatch方法,直接使用dispatch会抛出未定义错误 - 模板中仍错误访问props变量:已经通过
useSelector获取了状态值,但是模板里还在读取props.get_employees_total这类不存在的props属性,会导致渲染报错。
修正后的完整代码
import React, {useEffect} from 'react' import Stats from '../components/Stats' import {useTranslation} from 'react-i18next' // 替换connect为useDispatch、useSelector import { useDispatch, useSelector } from 'react-redux' import {getEmployeesTotal} from '../stores/employees' import {getVisitorsTotal} from '../stores/visitors' import {getCardsTotal} from '../stores/cards' function SimpleStats() { const {t} = useTranslation() // 声明dispatch const dispatch = useDispatch() const get_employees_total = useSelector((state)=>state.employees.get_employees_total.success) const get_visitors_total = useSelector((state) => state.visitors.get_visitors_total.success ) const get_cards_total = useSelector((state) => state.cards.get_cards_total.success) useEffect(() => { dispatch(getEmployeesTotal()) dispatch(getCardsTotal()) dispatch(getVisitorsTotal()) // dispatch引用是稳定的,不会变,加在依赖里不会有问题,也不会触发重复执行 }, [dispatch]) return ( <React.Fragment> <div className="container"> <div className="row quick-stats justify-content-md-center"> <Stats className="col" value={ get_employees_total !== null ? get_employees_total.meta.total : '...' } description={t('stats.EmployeesTotal')} /> <Stats className="col" value={ get_visitors_total !== null ? get_visitors_total.meta.total : '...' } description={t('stats.VisitorsTotal')} /> <Stats className="col" value={get_cards_total !== null ? get_cards_total.meta.total : '...'} description={t('stats.CardsTotal')} /> </div> </div> </React.Fragment> ) } export default SimpleStats
迁移注意事项
Redux Hooks完全支持和原有的connect写法共存,你可以逐个组件迁移,每改造完一个组件验证功能正常后再改下一个,不存在全量重构引入大量bug的风险。
内容的提问来源于stack exchange,提问作者osmancakirio
相关产品推荐
相关产品推荐

