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

时间:2018-04-09 05:30:27

标签: javascript reactjs ecmascript-6 redux reducers

我正在尝试使用react-redux来管理测试项目中的状态和道具。

例如,请考虑以下代码:(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')
)

这是我的组件代码:(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)

所以,如果我不使用联合收割机减速机,我打电话一次减速机就行了! 但结合后这不起作用,这没有任何反应...... 我的问题:我如何使用联合收割机减速机和状态?

我很抱歉,因为我的英语不好而且我写英语有很多错误: - )

谢谢

2 个答案:

答案 0 :(得分:3)

使用combineReducer时,您会获得以下状态:

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

由于reducers返回对象,实际状态为:

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

简单的解决方案是返回没有包装对象的值:

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
    }
}

现在状态将是:

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

答案 1 :(得分:2)

问题是你的reducer案例不尊重商店的先前状态,而是用全新的对象覆盖它。尝试使用此编辑的代码以便更好地理解。

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
    }
}

{... state,fieldToEdit:&#39; value&#39; }是一个声明,表示保留状态的所有值,但只更改我提供的密钥。 你的商店对象就像

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

所以使用{... state,count:1}就意味着

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

你在那里简单地覆盖整个对象。像这样

{
    count: 1
}

注意:...状态是es6传播操作符,您也可以使用

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

for es5

另外,检查您在CombineReducer中使用的密钥的名称,并使用相同的密钥访问组件中的数据,在您的情况下是counterReducer,因此您必须访问计数器,如state.counterReducer.count