Expo应用中Redux结合Axios-Thunk修改数组引发所有数组异常变化
问题根源定位
你现在遇到的多列表联动更新,和Axios返回的数组引用无关——就算你做了slice()生成新数组,问题的核心是三个独立reducer共用了完全没有业务标识的通用Action Type。
不管你是dispatch拉币种列表的action、拉支付方式的action、还是拉其他列表的action,触发的type全是FETCH_REQUEST_STARTED/FETCH_REQUEST_SUCCEED/FETCH_REQUEST_FAILURE。当任意一个请求完成dispatch对应action时,所有匹配了这几个通用type的reducer都会被触发执行,自然出现动一个全跟着变的情况。你之前为了规避引用复用问题加的Array.slice()操作其实属于无效操作,因为从逻辑上三个独立reducer根本不应该响应同一个全局action,只要type做了隔离,哪怕接口返回的是同一个数组引用,各reducer只处理自己对应action的payload,也不会出现状态串改。
落地解决步骤
- 给所有Action Type加专属业务前缀做隔离
废弃现在通用的无区分度的type定义,每个独立数据域的action必须绑定自己专属的type,避免全局匹配。比如把原来通用的三个type拆成对应业务场景的独立标识:- 币种列表相关:
CURRENCY_FETCH_START、CURRENCY_FETCH_SUCCESS、CURRENCY_FETCH_FAIL - 支付方式列表相关:
PAYMENT_METHOD_FETCH_START、PAYMENT_METHOD_FETCH_SUCCESS、PAYMENT_METHOD_FETCH_FAIL
对应修改你现有方法的action定义:
同步修改// 修改后的fetchMethods相关action,替换原来的通用type export const fetchMethodsStarted = () => ({ type: 'PAYMENT_METHOD_FETCH_START' }); export const fetchMethodsSuccess = meths => ({ type: 'PAYMENT_METHOD_FETCH_SUCCESS', payload: meths }); export const fetchMethodsFailure = error => ({ type: 'PAYMENT_METHOD_FETCH_FAIL', payload: error });reduceMethods里的switch匹配条件,只响应自己专属的三个type,其他action一律走default返回原状态。其他两个独立的列表reducer也按这个逻辑,匹配对应自己业务的专属type。 - 币种列表相关:
- 检查根Reducer的组合方式
确认你是通过Redux官方提供的combineReducers把三个独立reducer分别挂载到全局state的不同命名空间下,不要把三个reducer的逻辑硬塞到同一个switch分支里做手动路由,否则哪怕type做了隔离,也很容易出现状态串改的问题。
参考标准的组合写法:import { combineReducers } from 'redux'; import { reduceCurrencies } from './currencies/reducer'; import { reduceMethods } from './paymentMethods/reducer'; import { reducePaymentList } from './paymentList/reducer'; export const rootReducer = combineReducers({ currencyData: reduceCurrencies, methodData: reduceMethods, paymentListData: reducePaymentList }) - 补全两个容易踩的细节排查
- 如果接口返回的是嵌套对象结构,要确保更新状态时做正确的不可变更新,不要直接修改原state的属性值
- 检查组件的
mapStateToProps逻辑,不要错误引入其他reducer的状态绑定到当前组件props上,避免把其他数据源的更新误判为当前列表的联动修改
内容的提问来源于stack exchange,提问作者Joe's wiZa T
相关产品推荐
相关产品推荐

