You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Redux计数器组件无法读取默认状态技术求助

问题:React Redux计数器无法读取默认counter状态

我为计数器应用搭建了基础React Redux环境,无报错无警告,但组件无法读取counter的默认状态。代码如下:

const initialState = {counter:0}
const incrementReducer = (state = initialState, action)=> {
const {type, payload} = action;

  if (type == 'INCREMENT') {
    return {...state, counter:state.counter + 1 };
  }
return state;
}

const decrementReducer = (state = initialState, action)=> {
const {type, payload} = action;

  if (type == 'DECREMENT') {
    return {...state, counter:state.counter - 1 };
  }
return state;
}

const rootReducer = combineReducers({incrementReducer, decrementReducer});
  const store = createStore(rootReducer);
    // const store = createStore(incrementReducer);

function Counter() {
    const dispatch = useDispatch();
  const counter = useSelector((state) => state.counter);
  console.log({counter});
  return (
    <View style={styles.container}>
        <TouchableOpacity onPress={ () => dispatch({'type':'INCREMENT'})}>
      <Text style={styles.paragraph}>
        {counter}
      </Text>
          </TouchableOpacity>
    </View>
  );
}

export default function App() {
  return (
    <Provider store = {store}>
    <Counter/>
    </Provider>
  );
}

问题原因

核心问题是合并reducer后的状态结构与组件读取路径不匹配:

  • 使用combineReducers({incrementReducer, decrementReducer})后,Redux store的状态结构会变成:
    {
      incrementReducer: { counter: 0 },
      decrementReducer: { counter: 0 }
    }
    
  • 组件中useSelector((state) => state.counter)试图直接从根状态取counter,自然找不到对应值,结果为undefined。
  • 此外,两个reducer逻辑重复,各自维护独立的counter状态,不符合计数器的需求。

修复方案

方案1:合并为单个reducer(推荐)

用一个reducer处理所有计数器相关动作,简化状态结构:

import React from 'react';
import { View, Text, TouchableOpacity, StyleSheet } from 'react-native';
import { Provider, useDispatch, useSelector } from 'react-redux';
import { createStore } from 'redux';

const initialState = { counter: 0 };
// 单个reducer处理增减动作
const counterReducer = (state = initialState, action) => {
  switch (action.type) {
    case 'INCREMENT':
      return { ...state, counter: state.counter + 1 };
    case 'DECREMENT':
      return { ...state, counter: state.counter - 1 };
    default:
      return state;
  }
};

// 直接用单个reducer创建store
const store = createStore(counterReducer);

function Counter() {
  const dispatch = useDispatch();
  // 直接从根状态读取counter
  const counter = useSelector((state) => state.counter);

  return (
    <View style={styles.container}>
      <TouchableOpacity onPress={() => dispatch({ type: 'INCREMENT' })}>
        <Text style={styles.paragraph}>+</Text>
      </TouchableOpacity>
      <Text style={styles.paragraph}>{counter}</Text>
      <TouchableOpacity onPress={() => dispatch({ type: 'DECREMENT' })}>
        <Text style={styles.paragraph}>-</Text>
      </TouchableOpacity>
    </View>
  );
}

export default function App() {
  return (
    <Provider store={store}>
      <Counter />
    </Provider>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    gap: 20,
  },
  paragraph: {
    fontSize: 24,
  },
});

方案2:保留拆分reducer(不推荐)

如果坚持拆分reducer,需要调整组件的状态读取路径,但会导致两个独立的counter状态:

// 读取incrementReducer中的counter
const counter = useSelector((state) => state.incrementReducer.counter);

内容的提问来源于stack exchange,提问作者maddy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 16:32:42