我有以下组件在no-shadow
FilterButton
上触发props
ESlint错误。
import { setFilter } from '../actions/filter';
function FilterButton({ setFilter }) {
return (
<button onClick={setFilter}>Click</button>
);
}
export default connect(null, { setFilter })(FilterButton);
如何在保留mapDispatchToProps
和ESlint规则的简洁语法的同时避免警告?
我知道我可以添加注释来抑制警告,但是对每个组件执行此操作似乎都是多余且乏味的。
答案 0 :(得分:119)
这里有四个选项:
<强>为什么吗
这是避免ESLint错误的最简单方法。
为什么不呢?
使用react-redux
时,无阴影规则有助于防止出现非常常见的错误。也就是说,尝试调用原始的,未连接的操作(不会自动调度)。
换句话说,如果你不是使用解构并从道具中抓取动作,setFilter()
就不会调度动作(因为你直接调用导入的动作) ,而不是通过props.setFilter()
通过道具调用关联的动作,react-redux
会自动为您调度。
通过清理variable shadowing,您和/或您的IDE更有可能发现错误。
如何吗
在eslintConfig
文件中添加package.json
属性为one way to do this。
"eslintConfig": {
"rules": {
"no-shadow": "off",
}
}
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);
<强>为什么吗
通过明确使用道具对象的方法,您不必担心开始时出现阴影。
为什么不呢?
使用props
/ this.props
前置您的所有操作都是重复的(如果您要对所有其他非操作道具进行解构,则不一致)。
如何?
import { setFilter } from '../actions/filter';
function FilterButton(props) {
return (
<button onClick={props.setFilter}>Click</button>
);
}
export default connect(null, { setFilter })(FilterButton);
<强>为什么吗
简明扼要。
为什么不呢?
其他开发人员(或您未来的自己)可能无法理解正在发生的事情。根据您关注的风格指南,您可能会违反no-wildcard-imports rule。
如何吗
如果您只是从一个模块传递动作创建者:
import * as actions from '../actions/filter';
function FilterButton({ setFilter }) {
return (
<button onClick={setFilter}>Click</button>
);
}
export default connect(null, actions)(FilterButton);
如果您要传递多个模块,请使用object destructuring with rest syntax:
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);
答案 1 :(得分:7)
第五种选择:
eslintrc
规则允许特定的例外。module.exports = {
rules: {
'no-shadow': [
'error',
{
allow: ['setFilter'],
},
],
}
}
<强>为什么吗
你不想要变量阴影但在某些情况下无法绕过它。
为什么不呢?
您真的不希望代码库中存在变量阴影。
答案 2 :(得分:3)
第六个选项。
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行为。
答案 3 :(得分:2)
我调整了4.,实现了我想称呼的选项8。
为什么?
它具有与导入整个模块相同的优点,但不会与其他规则冲突,例如Do not use wildcard imports(airbnb)。
为什么不呢?
它添加了不必要的变量声明,可能会引起混乱。
如何?
对于单方法案例
import { setFilter as setFilterConnect } from '../actions/filter';
function FilterButton({ setFilter }) {
return <button onClick={setFilter}>Click</button>;
}
export default connect(
null,
{ setFilter: setFilterConnect }
)(FilterButton);
答案 4 :(得分:1)
在v7.1.0中添加了新的之后,您就可以完全删除变量和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;
答案 5 :(得分:0)
选项7 ...
为什么?
这是known pattern,您将获得额外的好处,那就是将组件与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);