it-roy-ru.com

Как разделить логику между редукторами Redux и создателями экшена?

У меня есть какая-то логика, которую я вставил в редуктор, который, я думаю, должен быть включен в действие и передан?

Это лучшая практика, чтобы поместить такие вещи в действия или редуктор?

Рабочий пример здесь .

Код редуктора:

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

Ваш редуктор должен быть чистым. В настоящее время это не чисто. Он вызывает deal(), который вызывает getRandom(), который опирается на Math.random() и, следовательно, не является чистым.

Этот вид логики («генерирование данных», будь то случайным образом или из пользовательского ввода) должен быть в действии создателя. Создатели действий не должны быть чистыми и могут безопасно использовать Math.random(). Создатель этого действия возвращает действие, объект, описывающий изменение

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

Редуктор просто добавит (или заменит?) Эти данные внутри состояния.

В общем, начать с объекта действия. Он должен описывать изменение таким образом, чтобы при работе редуктора с тем же объектом действия и тем же предыдущим состоянием возвращалось то же самое следующее состояние. Вот почему редуктор не может содержать вызовы Math.random() - они будут нарушать это условие, поскольку они будут случайными каждый раз. Вы не сможете проверить свой редуктор.

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

Наконец, не используйте классы внутри государства . Они не сериализуемы как есть. Вам не нужен класс Card. Просто используйте простые объекты и массивы.

63
Dan Abramov

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

Я полагаю, что имеет смысл сохранять чистоту в магазинах и цепочках действий.

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

0
Mardo

Насколько я понимаю, действия должны быть простыми объектами, которые содержат две вещи: (i) тип действия и (ii) что изменилось (то есть новые данные).

Редукторы, с другой стороны, являются чистыми функциями, которые принимают действия и предыдущее состояние приложения в качестве входных данных и возвращают новое состояние приложения. Как они этого добиваются, зависит от вас. Вы можете добавить любую логику, необходимую для принятия комбинации предыдущего состояния + действия и возврата нового состояния до тех пор, пока вы не мутируете данные вне своих функций-восстановителей.

Что касается вашего кода, я не уверен, что функция deal() принадлежит либо действию, либо редуктору. Я думаю, что лучшее место может быть в каком-то обработчике событий (например, onClick). Затем вы можете передать результаты запроса сделки в качестве действия вашему редуктору. 

0
Mark McKelvy