Redux Store中变量无法重置问题求助
搞定你的Redux状态更新问题!
嘿,作为Redux新手遇到这种时序问题太正常啦,我来帮你理清楚根源和解决办法~
你的核心问题是:Redux的状态更新是异步的,当你在componentDidMount里先调用clearData(),紧接着就拿this.props.currNum去请求数据时,Redux还没来得及把currNum改成0,所以你用的还是旧值。
为啥会这样?
简单说,Redux的dispatch发出动作后,reducer更新状态、组件拿到新props这个过程不是瞬间完成的。你在clearData()之后立刻读this.props.currNum,就像你刚按下开关,还没等灯亮就去摸灯泡——肯定还是原来的温度嘛。
给你几个实用的解决办法:
1. 用componentDidUpdate等状态更新完再请求
类组件里的componentDidUpdate可以帮你监听props变化,等currNum真的变成0了再发请求:
componentDidMount() { this.props.clearData(); // 先把分类ID存起来,避免重复获取 this.categoryId = this.props.navigation.getParam('categoryId', 1); } componentDidUpdate(prevProps) { // 只有当currNum从旧值变成0的时候,才触发请求 if (prevProps.currNum !== this.props.currNum && this.props.currNum === 0) { this.props.getLatestFormulasInCategory(this.categoryId, this.props.currNum); } }
2. 直接在clearData里触发数据请求(一步到位)
如果你不想折腾生命周期,可以把清除状态和请求数据的逻辑合并到一个action里:
// 修改你的clearData action clearData: (category) => { return (dispatch) => { // 先清除状态 dispatch({type: actionTypes.DATA_IN_CATEGORY_CLEAR}); // 直接调用获取数据的action,此时我们明确知道currNum是0,直接传就行 dispatch(getLatestDataInCategory(category, 0)); } } // 组件里这样调用 componentDidMount() { const categoryId = this.props.navigation.getParam('categoryId', 1); this.props.clearData(categoryId); }
3. 最简单的办法:直接传0当初始值
既然打开新窗口就是要从0开始加载,那你完全可以跳过读取props这一步,直接给getLatestFormulasInCategory传0:
componentDidMount() { this.props.clearData(); const categoryId = this.props.navigation.getParam('categoryId', 1); // 直接传0,不用等props更新 this.props.getLatestFormulasInCategory(categoryId, 0); }
这个办法最直接,适合你当前的场景——毕竟你明确知道新窗口的起始位置就是0嘛。
小彩蛋:简化你的reducer代码
你的reducer里的break其实没啥用,因为每个case里都有return,已经把函数执行终止了,去掉break代码会更清爽:
export const reducersDataInCategory = (state = initialStateDataInCategory, action) => { const {type, payload} = action switch(type) { case actionTypes.DATA_IN_CATEGORY_LOADING_ENABLED: return {...state, isLoading: true} case actionTypes.DATA_IN_CATEGORY_LOADING_DISABLED: return {...state, isLoading: false} case actionTypes.DATA_IN_CATEGORY_ADD_DATA: return {...state, data: [...state.data, ...payload.data], error: null} case actionTypes.DATA_IN_CATEGORY_ERROR: return {...state, error: payload.error} case actionTypes.DATA_IN_CATEGORY_ADD_NUM: return {...state, currNum: state.currNum + 30} case actionTypes.DATA_IN_CATEGORY_CLEAR: return {...state, currNum: 0, data: []} default: return state } }
内容的提问来源于stack exchange,提问作者Evansir
相关产品推荐
相关产品推荐

