首页 > 解决方案 > React Native - Redux combineReducers 不工作

问题描述

我尝试在 redux 中为计数器保存三个值。这是我的 combineReducers 文件:

import { combineReducers } from 'redux';

const SET_FREUNDE = 'SET_FREUNDE';
const SET_CHATS = 'SET_CHATS';
const SET_VOTES = 'SET_VOTES';

export function setFreunde(value) {
  return {
    type: SET_FREUNDE,
    value,
  }
}

export function setChats(value) {
  return {
    type: SET_CHATS,
    value,
  }
}

export function setVotes(value) {
  return {
    type: SET_VOTES,
    value,
  }
}

const defaults = [
  {
    countervotes: 1,
    counterchats: 1,
    counterfreunde: 1
  }
];


function counter(state=defaults, action) {
  switch (action.type) {
    case SET_FREUNDE:
      return [
        ...state,
        {
          ...state.counterfreunde = action.value
        }
      ];
      case SET_CHATS:
        return [
          ...state,
          {
            ...state.counterchats = action.value
          }
        ];
        case SET_VOTES:
          return [
            ...state,
            {
              ...state.countervotes = action.value
            }
          ];
    default:
      return state;
  }
}

const counters = combineReducers({
  counter
});

export default counters;

在我的 App.tsx 中,我创建了商店并想要获取值:

import { Provider, useSelector } from "react-redux";
import { createStore} from "redux";
import counters from './src/redux/counter';

const store = createStore(counters);

const AppStack = () => {
    const counterfreunde = useSelector((state)=>state.counterfreunde);
    const counterchats = useSelector((state)=>state.counterchats);
    const countervotes = useSelector((state)=>state.countervotes);
    return(
      ...
    )
   }

const App = () => {

  ...
    return(
        <Provider store={store} >
          <AppStack/>
        </Provider>
    );
  
}

export default App;

但是 counterfreunde, ... 是未定义的。如果我像这样直接在商店中设置值:

const store = createStore(() => ({
  counterfreunde: 1,
  counterchats: 1,
  counterfreunde: 1
}));

一切正常。我认为问题在于 combineReducer 的定义。

标签: react-nativeredux

解决方案


使用 时combineReducers,您为其提供了一个“Reducers Map Object”,该对象将状态的属性名称映射到控制该属性的 reducer。

const counters = combineReducers({
  counter
});

像上面这样调用combineReducers表示你的根状态有一个counter由你的counter减速器控制的属性。

单独来看这很好,但它会改变你的选择器,因为像这样的属性counterfreunde不是顶级状态的属性,它们是state.counter. 所以你的选择器需要是这样的:

const counterfreunde = useSelector((state) => state.counter.counterfreunde);

如果counter是您拥有的唯一减速器,那么您不需要使用combineReducers. counter你可以通过提供你的reducer 作为根状态的 reducer来保持你的选择器和现在一样。

function counter(state=defaults, action) {
  ...
}

// remove the combineReducers

export default counter;
const store = createStore(counter);

推荐阅读