首页 > 解决方案 > 如果有两个计数器组件要绑定到 Redux Store 中的两个属性,是否必须编写两次 reducer、mapStateToProps 等?

问题描述

如果在 React / Redux 页面上已经有一个带有+-按钮的计数器组件,中间有一个计数,对于countNoodle订购的面条数量,现在,假设我们要为 添加相同的计数器countDrink,我们是否必须编写所有的 reducer、mapStateToProps、actions、connect 等等,再一次?

当我们添加一个countSnack计数器时,再写一次所有这些行?

Store 状态如下所示:

{ countNoodle: 2, countDrink: 1, countSnack: 3}

所以现在 Store 只有{ count: 0 }. 当它需要一个与 绑定的计数器时{ countDrink: 0},是否必须再次编写以下 50 行代码(使用countDrinkincreaseDrinkDrink 的动作等)?什么时候countSnack需要添加,另外50行代码?

我可能期望只有一行,例如:

Instantiate(Counter, '#counterNoodle', store, 'countNoodle');

实际上,如果我们让Counteruse 使用本地状态,并让它使用回调将计数传递回父级,我们可以通过一行来实现:

<Counter updateCount={updateNoodleCount} />

但是如果我们使用 Redux,似乎我们必须有比这更多的代码。

现在这是一个计数器的代码:

// reducer.js
function reducer(state = { count: 0 }, action) {
    if (action.type === 'inc') {
        return { count: state.count + 1 }
    } else if (action.type === 'dec') {
        return { count: state.count - 1 }
    } else {
        return state;
    }
}

// Counter.js
import React from 'react';
import { connect } from 'react-redux';

function Counter(props) {
    return (
        <div>
            { props.name }
            <button onClick={props.incCount}> + </button>            
            {props.countValue}
            <button onClick={props.decCount}> - </button>
        </div>
    );
}

function mapStateToProps(state) {
    return {
        countValue: state.count
    }
}

// Action

const incAction = { type: 'inc' },
    decAction = { type: 'dec' };

function mapDispatchToProps(dispatch) {
    return {
        incCount: function () {
            return dispatch(incAction);
        },
        decCount: function () {
            return dispatch(decAction);
        }
    }
}

let connectedComponent = connect(
    mapStateToProps,
    mapDispatchToProps
)(Counter);

export default connectedComponent;

标签: reactjsreduxreact-redux

解决方案


在我看来,您应该让一个 reducer 递增,一个 reducer 递减,接收要更新的计数器,然后更新相应计数器的状态。不过,您必须为每个计数器映射StateToProps。

onClick={this.props.incrementCounter(countDrink)}
onClick={this.props.incrementCounter(countDrink)}


const incrementCounter(counterToUpdate){
    this.setState({ 
        ...state,
        [counterToUpdate]: this.state.[counterToUpdate] + 1
    })
}

const decrementCounter(counterToUpdate){
    this.setState({ 
        ...state,
        [counterToUpdate]: this.state.[counterToUpdate] - 1
    })   
}

在您的父组件中,您可以让 <Counter counter={this.props.countDrink} /> <Counter counter={this.props.countNoodle} /> <Counter counter={this.props.countSnack} /> 计数器收到一个道具,您将根据它保留计数的项目来传递该道具。


推荐阅读