【问题标题】:React.js and ES6: Any reason not to bind a function in the constructorReact.js 和 ES6:任何不在构造函数中绑定函数的理由
【发布时间】:2015-07-08 13:40:33
【问题描述】:

我正在将 React 组件更新为 ES6,遇到了这个问题中描述的问题 - Unable to access React instance (this) inside event handler - 即未绑定到组件实例。

这是有道理的,当然有效,但我对答案的另一部分感到困惑:

请注意,绑定函数会创建一个新函数。你可以 要么直接在渲染中绑定它,这意味着一个新函数将是 每次渲染组件时创建,或将其绑定到您的 构造函数,它只会触发一次。

constructor() {
  this.changeContent = this.changeContent.bind(this);
}

render() {
  return <input onChange={this.changeContent.bind(this)} />;
}

我假设构造函数中的绑定是性能等的首选方法,但你知道他们对 assume 的看法!

这两种方法的权衡是什么?有没有一种情况肯定比另一个更好?还是没关系?

【问题讨论】:

    标签: javascript reactjs this


    【解决方案1】:

    构造函数中绑定的缺点:react hot loader 不起作用。

    render() 中绑定的缺点:性能。


    最近我一直在做这个。它比渲染中的绑定稍快,但我愿意用性能换取灵活性和我梦寐以求的 HMR。

    render(){
      return <input onChange={(e) => this.handleChange(e.target.value)}>;
    }
    

    它提供了更多的灵活性,例如,更容易过渡到规范的 Input atom。

    render(){
      return <input onChange={(x) => this.handleChange(x)}>;
    }
    

    或者在你想要的地方添加参数:

    render(){
      return (
        <ul>
          {this.props.data.map((x, i) => {
            // contrived example
            return (
              <li 
                onMouseMove={(e) => this.handleMove(i, e.pageX, e.pageY)}>
              {x}
              </li>
            );
          }}
        </ul>
      );
    }
    

    【讨论】:

    • 你的第一点就足以说服我把它留在render()中。如果性能成为问题,我总是可以将其换成生产。
    • 我没有在我的项目中使用热加载器,我应该使用它。所有的先决条件(webpack 等)都在那里,只是想知道我可以通过 hot-loader 获得哪些主要增强功能?
    【解决方案2】:

    我想你只需要了解Function.prototype.bind() 将返回一个新函数。因此,您基本上每次都会通过在render() 方法中执行绑定操作来进行创建。 render() 方法被多次调用的几率真的很高。

    在构造函数中这样做意味着您最终只绑定一次,并且您可以根据需要多次重复使用它。即使render() 方法被多次调用,也会使用使用不同绑定上下文创建的同一个函数。

    是的,理想情况下您应该在构造函数中绑定。让我想起了几周前的piece of code(检查构造函数)。

    【讨论】:

      【解决方案3】:

      我认为您已经解决了与重新创建函数有关的主要问题。我想强调另一个使用箭头函数和属性初始化器的选项。这种情况下的箭头函数会自动采用本地的this

      例如

      class MyClass extends React.Component {
        changeComponent = (e) => {
          // this will refer to the component
        }
      
        render = () => {
          return <input onChange={this.changeContent} />;
        }
      }
      

      您可以在此处阅读更多信息:http://babeljs.io/blog/2015/06/07/react-on-es6-plus/

      当您有许多要绑定的功能时,这可能是一个更好的解决方案。但是,您确实失去了仅使用标准函数声明的简洁性。

      【讨论】:

      • 这可能比构造函数中的 .bind 慢,因为它必须为每个实例创建函数,而不仅仅是在同一个函数上创建 .bind。但这当然可以忽略不计:-)
      • 当 es6 的原生实现进入浏览器时会不会出现这个问题?或者这只是从 es6 转换到 es5 时的问题? @FakeRainBrigand
      • 嗯,这不是有效的 es6,所以......你会得到一个语法错误:-p 但性能因引擎和这些引擎的版本而异,所以没有正确的答案。跨度>
      • @FakeRainBrigand 抱歉,您是对的,这是针对属性初始化程序的计划提案。我已经修改了我的答案以考虑到这一点。可能暂时使这个答案完全无法使用,但无论如何我都会把它留在这里。
      • 它可供那些不介意实验性功能的人使用。我见过其他人就是这样做的。
      猜你喜欢
      • 2019-03-11
      • 1970-01-01
      • 2023-03-03
      • 2017-04-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-01
      • 2020-05-10
      相关资源
      最近更新 更多