我如何组成一个reduce来处理redux中的不同动作?

时间:2018-08-30 17:30:59

标签: javascript reactjs redux

我有一个简单的计数器应用程序,可以增加,减少并保持所有点击的总数。 Codesandbox - vanilla。我正在尝试在Redux中执行相同的操作,[Codesandbox-Redux] [1]。我认为问题是我如何构成总减速器。

actions.js

export const incrementNum = () => ({
  type: constants.TOTAL,
  type: constants.INCREMENT
});

export const decrementNum = () => ({
  type: constants.TOTAL,
  type: constants.DECREMENT
});

export const total = () => ({
  type: constants.TOTAL
});

reducers.js

const decreasedNum = (state = 0, action) => {
  switch (action.type) {
    case constants.DECREMENT:
      console.log("decrement was dispatched to decremnt reducer");
      console.log(state, action);
      return state - 1;
    default:
      return state;
  }
};

// takes a user click event and returns an action to send
// to other components
const increasedNum = (state = 0, action) => {
  switch (action.type) {
    case constants.INCREMENT:
      console.log("increment was dispatched to incremnet reducer", state);
      console.log(state, action);
      return state + 1;
    default:
      return state;
  }
};

const totalNum = (state = 0, action) => {
  let count = { num: 0, inc: 0, dec: 0 };
  switch (action.type) {
    case constants.INCREMENT:
      console.log("increment was dispatched to incremnet reducer ++++", state);
      //count.num = state +1;
      return state + 1;
    case constants.DECREMENT:
      console.log("decrement was dispatched to decremnt reducer ----");
      return state - 1;
    case constants.TOTAL:
      console.log("total is fired", state);
      count.num = state + 1;
      return state;
    default:
      return state;
  }
};

容器组件

class CounterContainer extends Component {
  constructor(props) {
    super(props);
  }

  render() {
    let number = this.props.totalNum;
    number = Math.abs(this.props.totalNum) + 1;
    console.log(number, this.props.totalNum, "component is getting props");
    return (
      <div>
        <h1>{this.props.totalNum}</h1>
        <div className="clicks">{this.props.totalNum}</div>
        <div className="button-container">
          <Decrement
            decrementNum={this.props.decrementNum}
            totalNum={this.props.total}
          />
          <Increment
            incrementNum={this.props.incrementNum}
            totalNum={this.props.total}
          />
        </div>
      </div>
    );
  }
}

function mapStateToProps(state) {
  return { totalNum: state.totalNum };
}

function mapDispatchToProps(dispatch) {
  return bindActionCreators({ incrementNum, decrementNum, total }, dispatch);
}

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

我的初衷是让增量和减量减速器同时传递到总计,对减量使用Math.abs并将它们加在一起。在我不断扔垃圾之前,我想了解我哪里出了问题,以及我要达到的最佳模式是什么。

2 个答案:

答案 0 :(得分:0)

我认为问题在于您要分派的有效载荷有多种类型。也许您正在寻找这样的东西:

actions.js:

export const incrementNum = () => {
  return dispatch => {
    dispatch({type: constants.TOTAL})
    dispatch({type: constants.INCREMENT})
  }
};

export const decrementNum = () => {
  return dispatch => {
    dispatch({type: constants.TOTAL})
    dispatch({type: constants.DECREMENT})
  }
}

export const total = () => ({
  type: constants.TOTAL
});

在查看沙箱后,我看到了您要得到的结果...因此,我将设置reducers以执行上述操作,例如:

reducer.js

export default handleActions({
  [constants.INCREMENT]: (state) => ({...state, inc: (state.inc+1)}),
  [constants.DECREMENT]: (state) => ({...state, dec: (state.dec+1)}),
  [constants.TOTAL]: (state) => ({...state, total: (state.total+1)})
}, {total: 0, inc: 0, dec: 0})

答案 1 :(得分:0)

这实际上应该由同一个减速器处理,我想您已经使它有些复杂了。

const initialState = {
  actionsHandled: 0,
  total: 0,
};

const increment = {
  type: 'INCREMENT',
};

const decrement = {
  type: 'DECREMENT',
};

const countReducer = (state = initialState, { type }) => {
  switch (type) {
    case 'INCREMENT':
      return {
        actionsHandled: state.actionsHandled + 1,
        total: state.total + 1,
      };
    case 'DECREMENT':
      return {
        actionsHandled: state.actionsHandled + 1,
        total: state.total - 1,
      };
    default:
      return {
        ...state,
        actionsHandled: state.actionsHandled + 1,
      };
  }
};

通过这种方式,您可以跟踪已处理的操作数/已被调用的次数,但是还可以使inc / dec起作用。您可以在化简器中修改状态的多个部分,而不必为每条数据都化简器。