React redux лучшие практики для сокращения кода

Что такое redux?

Redux – это библиотека JavaScript для управления состоянием приложения. Это контейнер предсказуемого состояния, который позволяет писать приложения, которые ведут себя последовательно независимо от того, что изменяет состояние.

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

Я не буду описывать здесь детали настройки redux.

Шаг:
Установите react-redux и redux с помощью npm

// Store.ts
import { combineReducers, createStore } from "redux";

// Reducer file
const counterReducer = (state = 0, { type, payload }) => {
  switch (type) {
    case "INCREMENT":
      return state + payload;
    case "DECREMENT":
      return state + payload;
    default:
      return state;
  }
};

// Action creator file
export const increment = (payload) => ({ type: "INCREMENT", payload });
export const decrement = (payload) => ({ type: "DECREMENT", payload });

// Store entrypoint file
const reducers = () =>
  combineReducers({
    counter: counterReducer,
  });

const store = createStore(reducers());

export default store;
Войдите в полноэкранный режим Выйти из полноэкранного режима
ПРИМЕЧАНИЕ: каждый раздел может быть перенесен в другой файл. Я пытаюсь сохранить простоту.

App.ts

export default function App() {
  const state = useSelector((state: any) => state);
  const dispatch = useDispatch();
  return (
    <div>
      <h1>Count: {state.counter}</h1>
      <button onClick={() => dispatch(increment(1))}>Increment</button>
      <button onClick={() => dispatch(decrement(-1))}>Decrement</button>
    </div>
  );
}
Вход в полноэкранный режим Выход из полноэкранного режима

index.ts

<Provider store={store}>
  <App />
</Provider>
Вход в полноэкранный режим Выход из полноэкранного режима

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


Как мы можем генерировать создателей действий автоматически?

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

Объект – это лучший способ управления вашим редуктором, он быстрее и легче читается. Мне не нравятся случаи switch, я предпочитаю объекты.

Switch может иметь временную сложность O(n), где n – количество случаев. Объект имеет временную сложность O(1). Посмотрите здесь некоторые другие лучшие практики

Файл редуктора

const counterReducerMap = {
  increment: (state, { payload }) => state + payload,
  decrement: (state, { payload }) => state + payload,
};

const counterReducer = (state = 0, action) => {
  const handler = counterReducerMap[action.type];
  return handler ? handler(state, action) : state;
};
Вход в полноэкранный режим Выход из полноэкранного режима

Создадим общую функцию создателя действия

const createAction = <T>(reducers): T => {
  return Object.keys(reducers).reduce((acc, type) => {
    acc[type] = (payload) => ({
      type,
      payload,
    });
    return acc;
  }, {} as T);
};

export const { increment, decrement } = createAction(counterReducerMap);
Вход в полноэкранный режим Выход из полноэкранного режима

Вы можете удалить общий тип, если используете javascript.

ПРИМЕЧАНИЕ: Важно заметить, что ключи карты редуктора – это ваши функции создателя действия. Это не функции редуктора.

Если вы будете следовать этому подходу, вы сможете сократить большое количество кодового кода. Этот подход также уменьшит размер производственного пакета.

Бонус для разработчиков typescript
type ActionCreator<A> = {
  [key in keyof A]: <T>(payload: T) => {
    type: key;
    payload: T;
  };
};

type Action = ActionCreator<typeof counterReducerMap>;
export const { increment, decrement } = createAction<Action>(counterReducerMap);
Вход в полноэкранный режим Выход из полноэкранного режима

Живой пример: здесь


Спасибо, что прочитали 😊

Есть вопросы или дополнительные? Пожалуйста, оставьте комментарий.


Обязательно к прочтению Если вы еще не
Лучшие практики и паттерны React для сокращения кода – часть 1
3 шага для создания пользовательской библиотеки управления состояниями с помощью React и Context API
Как отменить Javascript API запрос с помощью AbortController
13 Утилиты Typescript: Шпаргалка для разработчика

Больше материалов на Dev.to.
Ловите меня на Github, Twitter, LinkedIn, Medium и Stackblitz.

Оцените статью
Procodings.ru
Добавить комментарий