简体   繁体   English

何时在按钮 onClick 事件上使用内联函数 - Javascript/React.js

[英]When to use inline function on button onClick event - Javascript/React.js

I can see different style of assigning event handler to the button onClick event.我可以看到为按钮onClick事件分配事件处理程序的不同风格。 Can anyone suggest when to use inline function on button onClick event handler?任何人都可以建议何时在按钮onClick事件处理程序上使用内联函数?

onClick={props.handleDeleteOption(props.optionText)}; // Call the handler directly

onClick={(e) => {
          props.handleDeleteOption(props.optionText);
        }} // Call the handler through inline-function

Performance表现

Whether or not you use inline event handler functions it has an impact on the performance of the app.无论您是否使用内联事件处理函数,它都会影响应用程序的性能。

Inline event handlers are anonymous functions.内联事件处理程序是匿名函数。 They are created every time the component renders.每次组件渲染时都会创建它们。 That is, every time you call setState or when the component receives new props.也就是说,每次调用 setState 或组件收到新的 props 时。

Whenever a component is about to be rendered (when the state has been updated or receives new props,) react performs a shallow comparison between the previous DOM and the new DOM for that component.每当一个组件即将被渲染时(当状态被更新或接收到新的 props 时),react 会在之前的 DOM 和该组件的新 DOM 之间执行一个浅层比较。 If they are found to have different props from the props before the state update, then the component will re-render that particular component and all its child components.如果在状态更新之前发现它们具有与 props 不同的 props,则组件将重新渲染该特定组件及其所有子组件。 If not, it assumes the component is the same as the old DOM and so it doesn't render it.如果不是,则假定组件与旧 DOM 相同,因此不会渲染它。

Now inline functions are objects (functions are objects in javascript.) And when react compares functions, it does a strict comparison.现在内联函数是对象(函数是 javascript 中的对象。)当 react 比较函数时,它会进行严格的比较。 The inline function might not have changed in its value, but it is an entirely different function (different reference in memory) and so React detects that there has been a change.内联函数的值可能没有改变,但它是一个完全不同的函数(内存中的不同引用),因此 React 检测到发生了变化。 And when there is a change, React re-renders the component and all its children.当发生变化时,React 会重新渲染组件及其所有子组件。

Again, let me just state that performance decisions are usually largely tradeoffs.再说一次,我只想说明性能决策通常主要是权衡。 This explanation doesn't mean that you should remove all inline event handlers and define them at the class level.这种解释并不意味着您应该删除所有内联事件处理程序并在类级别定义它们。 This can slow down the first render for your component because of the binding that has to be done in the constructor.由于必须在构造函数中完成绑定,这可能会减慢组件的首次渲染速度。 There is also this thing called premature optimization which can lead to poor quality of code or it just might not be worth it.还有一种叫做过早优化的东西,它可能导致代码质量差,或者它可能不值得。

According to the ReactJS documentation:根据 ReactJS 文档:

<button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button>

<button onClick={this.deleteRow.bind(this, id)}>Delete Row</button>

The above two lines are equivalent, and use arrow functions and Function.prototype.bind respectively.上面两行是等价的,分别使用箭头函数和Function.prototype.bind。

In both cases, the e argument representing the React event will be passed as a second argument after the ID.在这两种情况下,表示 React 事件的e参数将作为 ID 之后的第二个参数传递。 With an arrow function, we have to pass it explicitly, but with bind any further arguments are automatically forwarded.使用箭头函数,我们必须显式传递它,但是使用 bind 任何进一步的参数都会自动转发。

This can be found at the bottom of this link: https://reactjs.org/docs/handling-events.html这可以在此链接的底部找到: https : //reactjs.org/docs/handling-events.html

The main difference is about how you wrote your function.主要区别在于您如何编写函数。 Examples from documentation :文档中的示例:

class LoggingButton extends React.Component {
  // This syntax ensures `this` is bound within handleClick.
  // Warning: this is *experimental* syntax.
  handleClick = () => {
    console.log('this is:', this);
  }

  render() {
    return (
      <button onClick={this.handleClick}>
        Click me
      </button>
    );
  }
}

And the second one:第二个:

class LoggingButton extends React.Component {
  handleClick() {
    console.log('this is:', this);
  }

  render() {
    // This syntax ensures `this` is bound within handleClick
    return (
      <button onClick={(e) => this.handleClick(e)}>
        Click me
      </button>
    );
  }
}

But as you can read in documentation, second approach is worse from performance perspective.但是正如您在文档中所读到的那样,从性能角度来看,第二种方法更糟。

onClick={props.handleDeleteOption(props.optionText)}; this will cause props.handleDeleteOption(props.optionText)} to be called without clicking the button.这将导致在不单击按钮的情况下调用props.handleDeleteOption(props.optionText)}

In javascript, let there be a function called foo , foo() will call the function whereas foo itself will be the reference to that function.在javascript中,假设有一个名为foo的函数, foo()将调用该函数,而foo本身将是对该函数的引用。

So when you do as in the second case, the function is passed to the onClick handler and will be triggered only onClick .因此,当您按照第二种情况进行操作时,该函数将传递给onClick处理程序,并且只会触发onClick The first line of code will not work as expected since it is being called there itself.第一行代码不会按预期工作,因为它本身是在那里调用的。 If you did not have to pass any data to the function, you could also have had written onClick={props.handleDeleteOption} (notice there are no brackets), and that would work as expected.如果您不必向函数传递任何数据,您也可以编写onClick={props.handleDeleteOption} (注意没有括号),这将按预期工作。

But since there is data, the only way you can write it is by onClick={(e) => {props.handleDeleteOption(props.optionText)}}但是因为有数据,所以你只能通过onClick={(e) => {props.handleDeleteOption(props.optionText)}}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM