简体   繁体   English

如何在react-redux中返回组合的减速器?

[英]How can I return combined reducers in react-redux?

I am trying to use react-redux for manage states and props in a test project. 我正在尝试使用react-redux在测试项目中管理状态和道具。

For example please consider this code : (Index.js) 例如,请考虑以下代码:(Index.js)

 import React, { Component } from 'react' import { render } from 'react-dom' import { Provider } from 'react-redux' import { createStore, combineReducers } from 'redux' import Counter from './counter' function counterReducer(state = {count: 0}, action) { switch(action.type) { case 'INCREMENT': return { count: state.count + 1 } break case 'DECREMENT': return { count: state.count - 1 } break default: return state } } function newsReducer(state = {news: 'default news'}, action) { switch(action.type) { case 'ONE': return { news: 'This is News one' } break case 'TWO': return { news: 'This is News two' } break default: return state } } const combine = combineReducers({ counterReducer, newsReducer, }) const store = createStore(combine) render( <Provider store={store}> <Counter /> </Provider>, document.getElementById('root') ) 

And this is my component code : (Counter.js) 这是我的组件代码:(Counter.js)

 import React, {Component} from 'react' import {connect} from 'react-redux' class Counter extends Component { constructor(props) { super(props) this.increment = this.increment.bind(this) this.decrement = this.decrement.bind(this) } increment() { this.props.dispatch({type: 'INCREMENT'}) } decrement() { this.props.dispatch({type: 'DECREMENT'}) } render() { return( <div> <h1>Counter</h1> <h3>{this.props.news}</h3> <h3>{this.props.count}</h3> <button onClick={this.increment}>+</button> <button onClick={this.decrement}>-</button> </div> ) } } function mapStateToProps(state) { return { count: state.count, news: state.news, } } export default connect(mapStateToProps)(Counter) 

So, if i do not use the combine reducer and I call once reducer this works ! 因此,如果我不使用组合式减速器,而我一次调用了这种减速器,那就行得通了! But after combine this not works and this have not any response ... My question: How can I use the combine reducers and states ? 但是在合并之后这是行不通的,并且没有任何响应...我的问题:如何使用合并化简器和状态?

I am so sorry, Because my English is not well and might be I have many mistakes to writing English :-) 很抱歉,因为我的英语不太好,可能是我在写英语时有很多错误:-)

Thank you 谢谢

When you use combineReducer you get the following state shape: 当您使用combineReducer您将获得以下状态形状:

{
   count: ...,
   news: ...
}

Since you reducers return objects, the actual state would be: 由于减速器返回对象,因此实际状态为:

{
   count: { count: ... },
   news: { news: ... }
}

The simple solution is to return the values without the wrapping object: 一个简单的解决方案是不带包装对象就返回值:

function counterReducer(state = 0, action) {
    switch(action.type) {
        case 'INCREMENT':
            return state.count
            break
        case 'DECREMENT':
            return state.count - 1
            break
        default:
            return state
    }
}

function newsReducer(state = 'default news', action) {
    switch(action.type) {
        case 'ONE':
            return 'This is News one'
            break
        case 'TWO':
            return 'This is News two'
            break
        default:
            return state
    }
}

And now the state would be: 现在的状态是:

{
   count: 0,
   news: 'default news'
}

The problem is that your reducer cases are not respecting the previous state of the store and is overriding it with entirely new object. 问题在于,reducer案例不尊重存储的先前状态,而是使用全新对象覆盖它。 Try this edited code for better understanding. 请尝试使用此编辑后的代码,以更好地理解。

function counterReducer(state = {count: 0}, action) {
    switch(action.type) {
        case 'INCREMENT':
            return { ...state, count: state.count + 1 }
            break;
        case 'DECREMENT':
            return { ...state, count: state.count - 1 }
            break
        default:
            return state
     }
}

function newsReducer(state = {news: 'default news'}, action) {
    switch(action.type) {
        case 'ONE':
            return { ...state, news: 'This is News one' }
            break
        case 'TWO':
            return { ...state, news: 'This is News two' }
            break
        default:
            return state
    }
}

The { ...state, fieldToEdit: 'value' } is a statement which says keep all the values of the state but only change the key I am providing. {... state,fieldToEdit:'value'}是一条语句,该语句表示保留状态的所有值,但仅更改我提供的键。 your store object was like 您的商店对象就像

{
    count: 0,
    news: 'Default news'
}

so on using { ...state, count: 1 } it means 如此使用{... state,count:1}表示

{
    news: 'Default news',
    count: 1
}

where as you simply overrided the entire object. 您只是在其中覆盖了整个对象。 like this 像这样

{
    count: 1
}

Note: ...state is an es6 spread operator you can also use 注意:... state是es6传播运算符,您也可以使用

Object.assign({}, state, { count: 1 }) 

for es5 对于es5

Also, check the names of the keys you used in CombineReducer and use the same keys to access data in your component which in your case is counterReducer so you have to access counter like state.counterReducer.count 另外,检查您在CombineReducer中使用的键的名称,并使用相同的键来访问组件中的数据(在您的情况下为counterReducer),因此您必须访问state.counterReducer.count之类的计数器

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM