Избегать ошибки тени без тени с помощью mapDispatchToProps

26

У меня есть следующий компонент, который вызывает ошибку no-shadow ESlint на FilterButton props .

import { setFilter } from '../actions/filter';


function FilterButton({ setFilter }) {
  return (
    <button onClick={setFilter}>Click</button>
  );
}

export default connect(null, { setFilter })(FilterButton);

Как я могу избежать предупреждения, сохраняя как сжатый синтаксис mapDispatchToProps , так и правило ESlint?

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

    
задан Kerumen 07.06.2016 в 16:53
источник
  • Вы можете переименовать setFilter (FilterButton ({setFilter}) в FilterButton ({setFilter})). Это имеет смысл (вроде), потому что функции, находящиеся в реквизитах FilterButton, на самом деле являются исходным setFilter с функцией отправки, связанной с ним. –  Gilad Artzi 07.06.2016 в 19:59
  • До и после переименования совпадают. –  Kerumen 08.06.2016 в 11:01
  • Я имел в виду переименование только в функции FilterButton ({setFilter}) {и <button onClick = {setFilter}> Нажмите </button>. Можете ли вы обновить свой вопрос с помощью отредактированного кода? –  Gilad Artzi 08.06.2016 в 11:21
  • Я не могу переименовать его в функции FilterButton ({setFilter}), потому что он должен соответствовать имени профайла, который на самом деле является setFilter. –  Kerumen 08.06.2016 в 11:58
  • Не можете ли вы просто переназначить, передав его функции в строке экспорта? Итак, экспорт по умолчанию connect (null, {filter: setFilter}) (FilterButton); а затем выше, просто функция FilterButton ({filter}) {(или любое другое новое имя переменной, которое вы предпочитаете). Таким образом, вы не затеняете переменную в верхней области, и это понятно при просмотре кода. –  Nick Bartlett 12.06.2016 в 20:55
Показать остальные комментарии

2 ответа

61

Здесь есть четыре варианта:

1. Отключите правило.

Почему?

Это самый простой способ избежать ошибки ESLint.

Почему не?

Правило no-shadow помогает предотвратить очень распространенную ошибку при использовании react-redux . То есть, попытка вызвать необработанное, несвязанное действие (которое автоматически не отправляется).

Другими словами, , если вы не были , используя деструктурирование и захват действия из реквизита, setFilter() не отправил действие (потому что вы будете ссылаться на импортированное действие напрямую, в отличие от вызывая подключенное действие через реквизит через props.setFilter() , который react-redux автоматически отправляет вам).

Очищая переменную тень , вы и / или ваша IDE с большей вероятностью возьмете ошибку.

Как?

Добавление свойства eslintConfig в ваш файл package.json один из способов сделать это .

"eslintConfig": {
    "rules": {
      "no-shadow": "off",
    }
  }

2. Переназначить переменную при передаче ее в connect() .

Почему?

Вы пользуетесь безопасностью правила no-shadow, и, если вы решите придерживаться соглашения об именах, оно очень явное.

Почему не?

Он вводит шаблон.

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

Если вы используете соглашение об именах, имена становятся длинными и повторяющимися.

Как?

Без соглашения об именах:

import { setFilter } from '../actions/filter';

function FilterButton({ filter }) {
  return (
    <button onClick={filter}>Click</button>
  );
}

export default connect(null, { filter: setFilter })(FilterButton);

С соглашением об именах:

import { setFilter, clearFilter } from '../actions/filter';

function FilterButton({ setFilterConnect, clearFilterConnect }) {
  return (
    <button onClick={setFilterConnect} onBlur={clearFilterConnect}>Click</button>
  );
}

export default connect(null, {
  setFilterConnect: setFilter,
  clearFilterConnect: clearFilter,
})(FilterButton);

3. Не разрушайте действия от реквизита.

Почему?

Явным образом используя метод off объекта реквизита, вам не нужно беспокоиться о затенении для начала.

Почему не?

Превращение всех ваших действий с props / this.props является повторяющимся (и непоследовательным, если вы разрушаете все ваши другие неактивные реквизиты).

Как?

import { setFilter } from '../actions/filter';

function FilterButton(props) {
  return (
    <button onClick={props.setFilter}>Click</button>
  );
}

export default connect(null, { setFilter })(FilterButton);

4. Импортируйте весь модуль.

Почему?

Это краткий.

Почему не?

Другие разработчики (или ваше будущее) могут не понимать, что происходит. И в зависимости от руководства по стилю, за которым вы следуете, вы можете нарушить правило без подстановочных знаков .

Как?

Если вы просто передаете создателей действий из одного модуля:

import * as actions from '../actions/filter';

function FilterButton({ setFilter }) {
  return (
    <button onClick={setFilter}>Click</button>
  );
}

export default connect(null, actions)(FilterButton);

Если вы передаете несколько модулей, используйте деструктурирование объекта с помощью синтаксис отдыха :

import * as filterActions from '../actions/filter';
import * as otherActions from '../actions/other';

// all exported actions from the two imported files are now available as props
function FilterButton({ setFilter, clearFilter, setOther, clearOther }) {
  return (
    <button onClick={setFilter}>Click</button>
  );
}

export default connect(null, { ...filterActions, ...otherActions })(FilterButton);

И так как вы упомянули о предпочтении сжатого синтаксиса ES6 в комментариях, также можете добавить функцию стрелки с неявным возвратом:

import * as actions from '../actions/filter';

const FilterButton = ({ setFilter }) => <button onClick={setFilter}>Click</button>;

export default connect(null, actions)(FilterButton);
    
ответ дан jabacchetta 20.02.2017 в 06:31
  • Спасибо! Это должен быть принятый ответ наверняка. –  Yan Takushevich 23.03.2017 в 12:13
  • Очень хорошо написан ответ. Хотя, следует прекратить чтение после отключения правила :) –  Mrchief 15.11.2017 в 16:38
  • Это тип ответа, который делает SO исключительным ресурсом, которым он является. –  Dan 20.04.2018 в 06:21
2

Пятый вариант:

5. Разрешить конкретное исключение с помощью правил eslintrc .

module.exports = {
  rules: {
    'no-shadow': [
      'error',
      {
        allow: ['setFilter'],
      },
    ],
  }
}

Почему?

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

Почему не?

Вы действительно не хотите, чтобы переменная затенения была в вашей базе кода.

ответ дан GollyJer 10.02.2018 в 02:03