Как мне составить один редуктор для обработки различных действий в редуксе? - PullRequest
0 голосов
/ 30 августа 2018

У меня есть простое приложение-счетчик, которое увеличивает, уменьшает и поддерживает общее количество кликов. Codesandbox - ваниль . Я пытаюсь сделать то же самое в 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 голосов
/ 31 августа 2018

На самом деле все это должно обрабатываться одним и тем же редуктором, я думаю, вы немного усложнили его.

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. Вы можете изменить несколько частей состояния в редукторе, вам не нужен редуктор на единицу данных.

0 голосов
/ 30 августа 2018

Я думаю, проблема в том, что у вас есть несколько типов полезных данных, которые вы отправляете. Может быть, это то, что вы ищете:

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

Посмотрев на песочницу, я вижу результат, к которому вы стремитесь ... Поэтому я бы настроил редукторы для выполнения описанных выше действий следующим образом:

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})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...