redux 使用mapDispatchToProps避免无阴影eslint错误

omvjsjqw  于 2023-01-13  发布在  其他
关注(0)|答案(6)|浏览(115)

我有以下组件在FilterButtonprops上触发no-shadow ESlint错误。

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

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

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

如何避免警告,同时保持mapDispatchToProps的简洁语法和ESlint规则?
我知道我可以添加一个注解来抑制警告,但是对每个组件都这样做似乎是多余和乏味的。

fcy6dtqo

fcy6dtqo1#

这里有四个选项:

1.禁用规则。

"为什么"
这是避免ESLint错误的最简单方法。

    • 为什么不**

no-shadow规则有助于防止在使用react-redux时出现一个非常常见的错误,即试图调用未连接的原始操作(不会自动调度)。
换句话说,如果您没有使用解构和从props获取动作,setFilter()将不会分派动作(因为您将直接调用导入的动作,而不是通过props.setFilter()调用连接的动作,react-redux会自动为您分派)。
通过清理variable shadowing,您和/或您的IDE更有可能发现该错误。

    • 怎么做**

eslintConfig属性添加到package.json文件中是one way to do this

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

2.将变量传递到connect()时重新赋值。

"为什么"
您可以从无阴影规则的安全性中获益,而且,如果您选择遵守命名约定,那么它是非常明确的。

    • 为什么不**

它引入了样板文件。
如果你不使用命名约定,你现在必须为每个动作想出一个替代的名字(仍然有意义),而且同样的动作很可能在不同的组件中被命名为不同的名字,这使得你很难熟悉动作本身。
如果使用命名约定,名称会变得很长且重复。

    • 怎么做**

无命名约定:

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.不要破坏 prop 的动作。

"为什么"
通过显式地使用props对象的方法,您不必担心一开始的阴影。

    • 为什么不**

在你所有的动作前面加上props/this.props是重复的(如果你正在解构你所有其他的非动作 prop ,这是不一致的)。

    • 怎么做**
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);

如果要传入多个模块,请使用带有rest语法的对象解构:

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简洁语法的偏好,那么不妨使用带隐式返回的arrow函数:

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

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

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

13z8s7eq2#

第五种选择:

5.通过eslintrc规则允许特定异常。

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

"为什么"
您不希望使用变量阴影,但在某些情况下无法绕过它。

    • 为什么不**

真的不希望在代码基中使用变量隐藏。😝

cotxawn7

cotxawn73#

第六种选择。

6.禁用特定代码行的es-lint规则

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

// eslint-disable-next-line no-shadow
function FilterButton({ setFilter }) {
  return (
    <button onClick={setFilter}>Click</button>
  );
}

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

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

/* eslint-disable no-shadow */
function FilterButton({ setFilter }) {
/* es-lint-enable */
  return (
    <button onClick={setFilter}>Click</button>
  );
}

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

第二种暂时禁用es-lint规则的方法与第一种不同,它可以用于多行代码,如果你传递更多的参数并将它们分成多行代码,它会很有用。
"为什么"
这是一个简单且适合某些用例的选项(例如,您的团队/组织使用特定的es-lint设置,不鼓励/禁止修改这些设置)。它禁用代码行中的es-lint错误,但不影响mapDispatchToProps语法,并且规则在代码行之外仍然完全有效。
"为什么不"
你不希望或者禁止用这样的注解来膨胀你的代码,你不希望或者禁止影响es-lint的行为。

3z6pesqy

3z6pesqy4#

我调整了4,得到了我想称之为选项8的东西。

8.以不同的名称导入方法

"为什么"
它与导入整个模块具有相同的优点,但不会与其他规则冲突,例如,不要使用通配符导入(airbnb)。
"为什么不"
它添加了一个不必要的变量声明,可能会引起混淆。

    • 怎么做**

对于单一方法情况

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

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

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

bz4sfanl5#

在v7.1.0中添加了新的Hooks API之后,您可以完全删除变量和mapDispatchToProps

import { useDispatch } from 'react-redux'
import { setFilter } from '../actions/filter';

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

export default FilterButton;
8qgya5xd

8qgya5xd6#

选项七...

7.使用容器组件

"为什么"
这是一个已知的模式,并且您还可以获得将组件从redux存储中分离出来的额外好处,从而使它们更易于重用。
"为什么不"
现在每个组件需要两个文件。

    • 怎么做**
// FilterButton.jsx

export default function FilterButton({ setFilter }) {
  return (
    <button onClick={setFilter}>Click</button>
  );
}
// FilterButtonRedux.jsx

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

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

相关问题