函数式组件中Redux dispatch后状态未立即更新问题咨询
问题根因
- 函数式组件的闭包特性:函数式组件每次渲染都会生成独立的闭包,本次渲染作用域内拿到的
props是固定不变的。你在then回调中访问的props.activity,属于发起请求那次渲染的闭包缓存值,即使Redux状态更新触发了组件重渲染,旧闭包里的props也不会同步更新,所以打印的还是旧值。 - 类组件无此问题的原因:类组件的
props挂载在this这个可变引用对象上,this.props永远指向最新的属性值,回调中访问时会读取到更新后的状态,因此不会出现类似问题。
无需使用useEffect的解决方案
- 方案1:直接使用接口返回值
你在then回调中已经拿到了完整的response,如果props.activity就是基于该响应数据更新的,直接从response中提取需要的字段使用即可,不需要额外读取Redux状态,是成本最低的改造方案。 - 方案2:直接调用store的
getState()方法
引入项目中导出的Redux store实例,在需要读取最新状态的位置直接调用store.getState()获取全局最新状态,示例代码如下:// 首先引入你的store实例 import store from '@/store' const getUserActivity = async () => { await props .get(displayDateString) .then((response) => { console.log(response); // 直接从store取最新状态 console.log(store.getState().activity); }) .catch((error) => console.log('error ' + error)); } - 方案3:改造异步Action返回所需状态
如果你用的是redux-thunk类异步中间件,可以改造ActivityReportActions.get这个异步action,在完成状态更新后把最新的activity值作为Promise的resolve值返回,你在then回调中直接接收即可,示例改造逻辑:// 改造前的action // const get = (date) => async (dispatch) => { // const res = await api.get(date) // dispatch({type: 'UPDATE_ACTIVITY', payload: res.data}) // } // 改造后的action const get = (date) => async (dispatch, getState) => { const res = await api.get(date) dispatch({type: 'UPDATE_ACTIVITY', payload: res.data}) // 更新完成后返回最新的activity值 return getState().activity } // 业务侧使用 const getUserActivity = async () => { await props .get(displayDateString) .then((latestActivity) => { console.log(latestActivity); // 直接拿到更新后的activity }) }
内容的提问来源于stack exchange,提问作者Johny Boy
相关产品推荐
相关产品推荐

