了解combineReducers

时间:2016-12-06 02:15:34

标签: reactjs redux

新的反应和减少,所以玩一些非常简单的代码,看看它是如何工作的。 当我尝试将combineReducers方法传递给redux存储时,我得到一个错误。如果我删除combinedReducers并将reducer直接传递到商店,一切正常。

let store = createStore(rootReducer);

错误

  

未捕获错误:对象作为React子对象无效(找到:对象   用键{reducer})。如果你想渲染一个孩子的集合,   使用数组或使用createFragment(object)包装对象   来自React附加组件。检查App的渲染方法。

使用combineReducers时为什么会出错?如果我想添加更多减速器怎么办?我认为这是什么结合了减速器?

main.js

import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { createStore, combineReducers } from 'redux';

import App from './components/app';

let reducer = (state=0, action) => {
  switch (action.type) {
    case 'INCREASE': 
            return state+1
    case 'DECREASE': 
            return state-1
    default: return state
  }
}

const rootReducer = combineReducers({
    reducer:reducer
});

let store = createStore(rootReducer);

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>
  , document.querySelector('.container'));

// app.js

import React, { Component } from 'react';
import {connect} from 'react-redux';

class App extends Component {
  render() {
        let {number, increase, decrease} = this.props
        return(
                <div>
              <div>{number}</div>
              <button onClick={e=>increase()}>+</button>
              <button onClick={e=>decrease()}> - </button>
            </div>
            );
     }
}

let mapStateToProps = state => ({
  number: state
})

let mapDispatchToProps = dispatch => ({
  increase: () => dispatch({type: 'INCREASE'}),
  decrease: () => dispatch({type: 'DECREASE'})
});

export default connect(mapStateToProps, mapDispatchToProps)(App);

3 个答案:

答案 0 :(得分:10)

Combine redurs采用reducers的哈希并返回一个reducer。生成的reducer表示与hash相同形状的对象。

所以,这样的电话:

combineReducers({ name: nameReducer})

会产生一个看起来像这样的状态对象:

{ name: 'Joe Shmo' }

在您的示例中,您正在生成一个如下所示的全局状态树:

{ reducer: 0 }

但是你试图在你的number中提取一个名为mapStateToProps的属性。

如果您将减速器声明更改为如下所示:

const number = (state=0, action) => {
  switch (action.type) {
    case 'INCREASE': 
            return state+1
    case 'DECREASE': 
            return state-1
    default: return state
  }
}
const rootReducer = combineReducers({
    number
});

然后将您的mapStateToProps更改为:

const mapStateToProps = ({number}) => ({number});

您的代码应该开始工作。

答案 1 :(得分:3)

https://redux.js.org/docs/basics/Reducers.html

import { combineReducers } from 'redux'

const todoApp = combineReducers({
  visibilityFilter,
  todos
})

export default todoApp

请注意,这相当于:

export default function todoApp(state = {}, action) {
  return {
    visibilityFilter: visibilityFilter(state.visibilityFilter, action),
    todos: todos(state.todos, action)
  }
}

你也可以给他们不同的键,或者以不同的方式调用函数。编写组合减速器的这两种方法是等效的:

const reducer = combineReducers({
  a: doSomethingWithA,
  b: processB,
  c: c
})
function reducer(state = {}, action) {
  return {
    a: doSomethingWithA(state.a, action),
    b: processB(state.b, action),
    c: c(state.c, action)
  }
}

不要忘记连接每个部分

@connect(state => ({
  reducerName: state[partStoreName]
}))

答案 2 :(得分:0)

我相信您也可以做到:

const INITIAL_STATE = { number: 0 };

export default (state = INITIAL_STATE, action) => {
  switch (action.type) {
    case 'INCREASE': 
            return state+1
    case 'DECREASE': 
            return state-1
    default: return state
  }
};