React Native + Redux应用Reducer未调用问题排查求助
我仔细梳理了你的代码,找到了几个核心问题,正是这些问题导致Reducer没有被正确触发,或者触发后无法产生预期的状态更新。咱们一步步来修复:
1. Reducer中存在无效返回值和逻辑漏洞
你的Reducer代码里有两个致命问题:
GET_MARKET_CAPcase里写了return ;,这会返回undefined,直接破坏Redux的状态树,导致后续所有Action的处理都异常。GET_MARKET_CAP_SUCCESScase没有返回新的State对象,会直接执行到下一个case,导致状态更新混乱。
修复后的Reducer代码:
import { combineReducers } from 'redux'; import { GET_MARKET_CAP, GET_MARKET_CAP_SUCCESS, GET_MARKET_CAP_FAIL, GET_GLOBAL_INFO } from '../actions'; const initialState = { isFetching: false, data: '', hasError: false, errorMessage: null, marketCap: null, // 提前初始化需要用到的字段 bitcoinPercentage: null }; export default function reducer(state = initialState, action) { switch (action.type) { case GET_MARKET_CAP: console.log('触发GET_MARKET_CAP'); return { ...state, isFetching: true }; // 必须返回新的State对象 case GET_MARKET_CAP_SUCCESS: console.log('GET_MARKET_CAP_SUCCESS触发'); return { ...state, isFetching: false, marketCap: action.data[0]['market_cap_krw'], // 对应Action传递的data结构 hasError: false }; case GET_MARKET_CAP_FAIL: return { ...state, isFetching: false, hasError: true, errorMessage: action.err }; case GET_GLOBAL_INFO: console.log('GET_GLOBAL_INFO触发', action); return { ...state, bitcoinPercentage: action.data.bitcoin_percentage_of_market_cap // 匹配API返回的字段名 }; default: return state; } }
2. Action与Reducer的字段不匹配
在getGlobalInfo Action中,你dispatch的是完整的data对象,但Reducer里却试图读取action.bitcoinPercentage,这明显对应不上。API返回的全局信息里,比特币占比的字段是bitcoin_percentage_of_market_cap,所以要从action.data里正确取值。
3. mapStateToProps的字段映射错误
你的mapStateToProps里写了state.market,但Reducer的State中根本没有market这个字段,你应该映射的是Reducer里定义的marketCap字段:
const mapStateToProps = (state) => { return { market: state.marketCap, // 对应Reducer中的marketCap字段 bitcoinPercentage: state.bitcoinPercentage }; };
4. 检查Reducer的导入路径
你的store.js里写了import reducer from '../reducers';,如果你的Reducer文件是reducers/reducer.js,那路径应该改成import reducer from '../reducers/reducer';,路径错误会导致Store加载不到Reducer,自然不会触发任何Reducer逻辑。
5. 组件中API调用的冗余处理
在Market.js的componentDidMount里,你写了:
this.props.getMarketCap('bitcoin', 'KRW').then(data => data[0]['market_cap_krw']);
这里的then是多余的,因为getMarketCap返回的Promise是Action的执行结果,而API返回的数据已经通过dispatch传递给Reducer了,你只需要调用方法即可:
componentDidMount() { this.props.getMarketCap('bitcoin', 'KRW'); this.props.getGlobalInfo(); }
最后,建议开启Redux DevTools来调试,这能让你直观看到Action是否被dispatch、State的变化情况。只需要取消store.js里的注释即可:
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose; export const store = createStore( reducer, composeEnhancers( applyMiddleware(thunk) ) );
按照这些步骤修复后,你的Reducer应该能正常触发并更新State了。
内容的提问来源于stack exchange,提问作者himori123

