如何解决功能组件上的 jsx-no-bind 错误?

Bon*_*Fir 10 javascript jsx reactjs

我有一个小组件可以更改我网站的语言。由于 eslint 配置为jsx-no-bind,因此它会在以下代码中引发错误。

const ChangeLanguage = ({ toggleLanguage }) => {

    const toggle = () => {
        console.log('hi')
        toggleLanguage()
    }

    return (
        <IconButton
            onClick={toggle}
        >
            <Language /> // this is an svg-icon
        </IconButton>
    )
}

export default connect(null, { toggleLanguage })(ChangeLanguage)
Run Code Online (Sandbox Code Playgroud)

我用谷歌搜索了jsx-no-bind用法。有人说我们应该启用它,因为在每个渲染中 javascript 都会生成新函数,并导致不必要的渲染(如 Airbnb 代码约定[链接])。但其他一些人表示,它的性能改进可以忽略不计,并且降低了代码的可读性(就像这个[链接])。这里有两个问题:

  1. 如何解决该错误(即不禁用jsx-no-bind)。
  2. 您对配置有什么建议jsx-no-bind(即我是否应该从 eslint 配置中完全/部分删除它?)。

PS:网上有更多关于将箭头函数或绑定方法作为 props 传递的文档。但我在问题陈述中只提到了其中两个。

Hen*_*k N 5

该解决方案记录在此处:https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-no-bind.md#react-hooks

函数式组件通常与钩子一起使用,如果您的回调完全独立于您的状态,那么最简单的情况就会发生。在这种情况下,解决方案就像将回调移出组件一样简单:

const onClick = () => {
  console.log("Independent callback");
};
const Button = () => {
  return (
    <button type="button" onClick={onClick}>Label</button>
  );
};
Run Code Online (Sandbox Code Playgroud)

否则,避免在每个渲染上重新定义回调的惯用方法是使用钩子来记忆它们useCallback

const Button = () => {
  const [text, setText] = useState("Before click");
  const onClick = useCallback(() => {
    setText("After click");
  }, [setText]); // Array of dependencies for which the memoization should update
  return (
    <button type="button" onClick={onClick}>{text}</button>
  );
};
Run Code Online (Sandbox Code Playgroud)


小智 2

发生这种情况是因为您在组件的 return 语句中传递了一个函数,并且每次组件重新呈现时都会创建一个新函数。

为了避免这种情况,您只能使用它的引用。像这样,

const ChangeLanguage = ({ toggleLanguage }) => {
return (
    <IconButton
        onClick={toggleLanguage} // <----->
        <Language /> // this is an svg-icon
    </IconButton>
 )
}
Run Code Online (Sandbox Code Playgroud)

export default connect(null, { toggleLanguage })(ChangeLanguage)