Как настроить ESLint и Prettier в React приложении

2 года назад·1 мин. на чтение

Как быстро настроить ESLint и Prettier

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

Что такое ESLint?

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

Что такое Prettier?

Prettier — это модуль форматирования кода, совместимый с большинством языков. Это экономит много времени. Он быстро делает отступ в нашем коде при сохранении (зависит от настроек VSCode/редактора). Чтобы включить форматирование кода при сохранении в VSCode, нужно перейти в File -> Preferences -> Settings. Далее в строке поиска настроек вставим Format On Save. В найденном поле ставим галочку.

Как заставить их работать вместе?

В ESLint также есть правила форматирования, которые могут конфликтовать с Prettier. Поэтому мы должны аккуратно их настроить (звучит сложно, но на деле это очень просто). Давайте начнём

Шаг 1

npm install eslint --save-dev

# или

yarn add eslint --dev

Шаг 2:

Создайте .eslintrc.json выполнив команду
npx eslint --init

# или

yarn run eslint --init

Шаг 3

В React 17.0.0 импорт react в файл необязателен. Чтобы исправить это, мы добавим правило в наш файл .eslintrc. Итак, откройте файл .eslintrc и добавьте эту строку "react/react-in-jsx-scope": "off" внутри rules.
  "rules": {
    "react/react-in-jsx-scope": "off"
  }

Шаг 4

Если вы используете jest, вы обнаружите, что eslint выдает нам ошибку, что test или expect не определены. Чтобы это исправить, нам нужно добавить "jest": true внутрь env.
  "env": {
    "browser": true,
    "es2021": true,
    "jest": true
  }

Шаг 5

Теперь добавьте плагины eslint, чтобы он работал с react, и сделайте правильную конфигурацию для eslint и prettier, чтобы они не конфликтовали друг с другом. Установите:
npm install eslint-config-prettier eslint-plugin-prettier prettier --save-dev

# или 

yarn add eslint-config-prettier eslint-plugin-prettier prettier --dev
eslint-config-prettier — отключает все правила, которые не нужны или могут конфликтовать с Prettier. eslint-plugin-prettier - Запускает Prettier как правило ESLint. После установки выше внесите изменения в файл .eslintrc.
 "extends": [
  "eslint:recommended",
  "plugin:react/recommended",
  "plugin:prettier/recommended"
]
Мы можем запустить Prettier отдельно, но мы хотим, чтобы eslint запустил его для нас, чтобы он не конфликтовал с правилами eslint.

Шаг 6

Создайте .prettierrc и вставьте приведенный ниже код
{
  "semi": true,
  "tabWidth": 2,
  "printWidth": 100,
  "singleQuote": true,
  "trailingComma": "none",
  "jsxBracketSameLine": true
}
Теперь, eslint and prettier установлены и мы можем добавить скрипт в package.json.
"lint": "eslint .",
"lint:fix": "eslint --fix",
"format": "prettier --write './**/*.{js,jsx,ts,tsx,css,md,json}' --config ./.prettierrc"
Это должно сработать, но прежде чем тестировать, лучше перезапустить VSCode.

Кастомный хук для диспатчинга Redux экшенов

2 года назад·1 мин. на чтение

В этой статье напишем кастомный хук для вызова action creator’а Redux вместе с dispatch() внутри.

Часто, вызывая action creator, мы забываем обернуть его в dispatch(), а вместо этого вызываем как обычная функцию. Таким образом action не доходит до редьюсера.
addProductToCart(product); // не верно
dispatch(addProductToCart(product)); // верно
Мы создадим собственный хук, в котором будет выполняться обертывание вызова функции в dispatch(), чтобы мы могли отправлять наши экшены, вызывая их как обычные функции с уже встроенным диспатчингом.
import { useCallback } from 'react';
import { useDispatch } from 'react-redux';

export const useWithDispatch = (fn) => {
  const dispatch = useDispatch();

  return useCallback(
    payload => () => dispatch(fn(payload)),
    [dispatch, fn]
  ) 
}
Реализация довольно проста. useWithDispatch — это функция высшего порядка, поскольку она принимает функцию (action creator) в качестве аргумента и возвращает другую функцию, которая при вызове вызовет переданную функцию, обернутую с помощью dispatch(). Обязательно запоминаем функцию обратного вызова с помощью useCallback.
Допустим, мы работаем над приложением списка задач, и у нас есть действие addTask(), которое берет текст задачи и добавляет его в список задач:
// actions.js

const addTaskAction = (text) => {
  return {
    type: 'ADD_TASK',
    payload: {
      id: 'some-id',
      text
    }
  }
}
В компоненте вызов будет выглядеть следующим образом.
import { addTaskAction } from './actions';

export const Component = () => {
  const addTask = useWithDispatch(addTaskAction);

  const handleClick = () => {
    addTask('Learn Redux');
  }

  // ...
}

Итоги

Я надеюсь, что вы нашли этот пост полезным. Вам по-прежнему нужно помнить о передаче создателей действий (action creator) в useWithDispatch, но будет легче запомнить, что вы делаете это в самом начале, а не при их вызове.