Отправка действия за действием

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

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

export function enthusiasm(state: StoreState, action: UsersAction): StoreState {

  let globalEnthusiasmLevel: number;

  switch (action.type) {

    case INCREMENT_ENTHUSIASM:

      state.users = state.users.map((user: UserType) => {

        if (user._id === action.payload._id) {
          user.enthusiasmLevel = user.enthusiasmLevel + 1;
        }

        return user;
      });

      globalEnthusiasmLevel = state.globalEnthusiasmLevel + 1;
      return { ...state, globalEnthusiasmLevel };

    case DECREMENT_ENTHUSIASM:

      const users: UserType[] = state.users.map((user: UserType) => {

        if (user._id === action.payload._id) {
          globalEnthusiasmLevel = (user.enthusiasmLevel > 0 ) ? state.globalEnthusiasmLevel - 1 : state.globalEnthusiasmLevel;

          user.enthusiasmLevel = user.enthusiasmLevel - 1;
          user.enthusiasmLevel = Math.max(0, user.enthusiasmLevel);
        }

        return user;
      });

      return { ...state, ...users, globalEnthusiasmLevel };

    case STORE_USERS:
      return { ...state, users: action.payload };

    case SET_GLOBAL_ENTHUSIASM:
      return { ...state, globalEnthusiasmLevel: action.payload };

    default:
      return state;
  } 
  1. Каков наилучший подход к отправке действия после действия?
  2. разумно ли разделить STORE_USERS и SET_GLOBAL_ENTHUSIASM на другой редуктор?
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
0
0
64
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

1 — Вы можете написать промежуточное ПО для обработки побочных эффектов типа действия INCREMENT_ENTHUSIASM и DECREMENT_ENTHUSIASM. Следующий пример написан на ES6, поэтому вам нужно будет перевести его на Typescript.

const middleware = store => next => action => {
  next(action);
  switch (action.type) {
    case INCREMENT_ENTHUSIASM:
      store.dispatch({
        type: INCREMENT_GLOBAL_ENTHUSIASM // increment global value
      });
      break;
    case DECREMENT_ENTHUSIASM:
      store.dispatch({
        type: DECREMENT_GLOBAL_ENTHUSIASM // decrement global value
      });
      break;
    default:
      break;
  }
}

...
import { createStore, combineReducers, applyMiddleware } from 'redux';

const store = createStore(
  combineReducers({
    enthusiasm
  }),
  applyMiddleware(middleware)
);

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

2 - Если вы собираетесь хранить globalEnthusiasmLevel в другом редукторе, то да, так и должно быть. Но см. мое замечание выше о том, чтобы не хранить, а вычислять его.

1. это работает как шарм. Насколько я понимаю, функциональность промежуточного программного обеспечения выполняется ПОСЛЕ начального действия, верно? Таким образом, последний всегда работает с последним/текущим состоянием. 2. что здесь лучше всего? Например, я сохраняю пользователей, поступающих из бэкэнда, в том же редукторе (STORE_USERS). Это не кажется правильным, думаю, это должно быть отдельно?

San Jay Falcon 30.04.2019 14:37

о вашем замечании But if globalEnthusiasmLevel can be calculated from all users' enthusiasm levels, then how about not storing them in store, but calculated it in mapStateToProps when you need to use in React component instead? >> правда, но это для практики и понимания.

San Jay Falcon 30.04.2019 14:52

@SanJayFalcon о вашем втором вопросе, это чисто личное предпочтение. Лично я буду нормализовать данные API до тех пор, пока они не станут плоскими, как таблицы БД, и создам редукторы для каждой «таблицы», то есть массива данных, и создам отдельные типы действий для каждого редуктора. Но у этого парня другое мнение, и я тоже считаю его правильным: stackoverflow.com/a/35494345/2404452. Итак, в конце концов, просто структурируйте свой магазин так, как вам удобно и имеет смысл.

blaz 30.04.2019 15:07

@SanJayFalcon около 1 - поскольку я поставил next(action) первым, промежуточное программное обеспечение будет ждать, пока не будет выполнено 1-е действие, чтобы продолжить. Вы можете использовать промежуточное программное обеспечение, чтобы выполнить что-то раньше, изменить действие или завершить действие — настолько оно гибко.

blaz 30.04.2019 15:11

очень обязан господин! очень полезно

San Jay Falcon 01.05.2019 17:10

Другие вопросы по теме