如何在Redux reducer和动作创建者之间划分逻辑? [英] How to divide the logic between Redux reducers and action creators?

查看:61
本文介绍了如何在Redux reducer和动作创建者之间划分逻辑?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在减速器中输入了一些逻辑,我认为应该将其放入Action中并传递下去?

将这种东西放入动作或减速器中是最佳实践吗?

工作示例此处.

减速器代码:

function Card() {
  this.card = (Math.random()*4).toFixed(0);
}

Card.prototype = {
  getRandom: function(){
    var card;
    //console.log(this.card)
    switch (this.card) {
      case '1':
      card = 'heart';
      break;
      case '2':
      //card = 'diamonds';
      card = 'heart'; // weight the odds abit
      break;
      case '3':
      card = 'club';
      break;
      case '4':
      card = 'spade';
      break;
      default:
      card = 'heart';
      break;
    }
    return card;
  }
}

var dealer = {
  deal: function(){
    var results = [];
    for(var i = 0; i <4; i++){
      var card = new Card();
      results.push(card.getRandom());
    }
    console.log(results);
    return results;
  }
}


const initialState = {
  count: 0,
  data: []
}

function counter (state = initialState, action) {
  let count = state.count
  switch (action.type) {
    case 'increase':
      return Object.assign({}, state, {
        data: dealer.deal(),
        count: state.count+1
      })
    default:
      return state
  }
}

解决方案

您的减速器必须是纯净的.当前它不是纯净的.它会调用deal(),后者会调用getRandom(),而该getRandom()依赖于Math.random(),因此并不纯.

这种逻辑(无论是随机生成还是来自用户输入的生成数据")都应在动作创建者中使用.动作创建者不必太单纯,可以安全地使用Math.random().该操作创建者将返回一个操作,描述更改的对象:

{
  type: 'DEAL_CARDS',
  cards: ['heart', 'club', 'heart', 'heart']
}

Reducer只会在状态内添加(或替换?)此数据.

通常,从动作对象开始.它应该以这样的方式描述更改:使用相同的动作对象和相同的先前状态运行reducer应该返回相同的下一状态.这就是为什么reducer不能包含Math.random()调用的原因-它们将打破此条件,因为它们每次都是随机的.您将无法测试减速器.

弄清楚动作对象的外观后(例如上面的样子),您可以编写动作创建者来生成它,并编写一个reducer来将状态和动作转换为下一个状态. 生成动作的逻辑驻留在动作创建者中,对其做出反应的逻辑驻留在化简器中,化简器必须是纯净的.

最后,不要在州内使用课程.它们不能按原样序列化.您不需要Card类.只需使用普通对象和数组即可.

I have some logic that I've put in the reducer which I'm thinking should be possibly put in the Action and passed down?

Is it best practice to put this sort of stuff in the actions or reducer?

Working example here.

Reducer code:

function Card() {
  this.card = (Math.random()*4).toFixed(0);
}

Card.prototype = {
  getRandom: function(){
    var card;
    //console.log(this.card)
    switch (this.card) {
      case '1':
      card = 'heart';
      break;
      case '2':
      //card = 'diamonds';
      card = 'heart'; // weight the odds abit
      break;
      case '3':
      card = 'club';
      break;
      case '4':
      card = 'spade';
      break;
      default:
      card = 'heart';
      break;
    }
    return card;
  }
}

var dealer = {
  deal: function(){
    var results = [];
    for(var i = 0; i <4; i++){
      var card = new Card();
      results.push(card.getRandom());
    }
    console.log(results);
    return results;
  }
}


const initialState = {
  count: 0,
  data: []
}

function counter (state = initialState, action) {
  let count = state.count
  switch (action.type) {
    case 'increase':
      return Object.assign({}, state, {
        data: dealer.deal(),
        count: state.count+1
      })
    default:
      return state
  }
}

解决方案

Your reducer must be pure. Currently it is not pure. It calls deal() which calls getRandom() which relies on Math.random() and thus is not pure.

This kind of logic ("generating data", whether randomized or from user input) should be in the action creator. Action creators don’t need to be pure, and can safely use Math.random(). This action creator would return an action, an object describing the change:

{
  type: 'DEAL_CARDS',
  cards: ['heart', 'club', 'heart', 'heart']
}

The reducer would just add (or replace?) this data inside the state.

In general, start with an action object. It should describe the change in such a way that running the reducer with the same action object and the same previous state should return the same next state. This is why reducer cannot contain Math.random() calls—they would break this condition, as they would be random every time. You wouldn't be able to test your reducer.

After you figure out how the action object looks (e.g. like above), you can write the action creator to generate it, and a reducer to transform state and action to the next state. Logic to generate an action resides in action creator, logic to react to it resides in the reducer, reducer must be pure.

Finally, don’t use classes inside the state. They are not serializable as is. You don’t need a Card class. Just use plain objects and arrays.

这篇关于如何在Redux reducer和动作创建者之间划分逻辑?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆