在 React 中正确使用箭头函数

我正在使用带有 Babel 和 Webpack 的 ReactJS,并使用 ES6 以及 提议的类字段 用于箭头功能.我了解箭头函数通过 not重新创建每个渲染的函数,类似于构造函数中的绑定工作方式.但是,我不能 100% 确定我是否正确使用它们.以下是我在三个不同文件中的代码的简化部分.

I am using ReactJS with Babel and Webpack and using ES6 as well as the proposed class fields for arrow functions. I understand that arrow functions make things more efficient by not recreating the functions each render similar to how binding in the constructor works. However, I am not 100% sure if I am using them correctly. The following is a simplified section of my code in three different files.

我的代码:

Main.js

prevItem = () => {
    console.log("Div is clicked")
}

render(){
    return (
         <SecondClass prevItem={this.prevItem} />
    )
}

SecondClass.js

SecondClass.js

<ThirdClass type="prev" onClick={()=>this.props.prevItem()} />

ThirdClass.js

ThirdClass.js

<div onClick={()=>{this.props.onClick()}}>Previous</div>

问题:

我上面的代码是否正确使用了箭头函数?我注意到对于 SecondClass.js,我也可以使用:

Is my code above using the arrow functions correctly? I noticed that for SecondClass.js I could have also used:

<ThirdClass type="prev" onClick={this.props.prevItem} />

由于我在原始函数定义中使用了 ES6 箭头函数,因此一种方法或另一种方法有区别吗?或者我应该一直使用箭头语法直到我的最后一个 div?

Is there a difference between one method or the other since I used an ES6 arrow function in my original function definition? Or should I be using the arrow syntax all the way through until my last div?

推荐答案

我知道箭头函数可以让事情变得更有效率重新创建每个呈现的函数类似于在构造函数工作.

I understand that arrow functions make things more efficient by not recreating the functions each render similar to how binding in the constructor works.

这不是真的.这取决于您使用箭头功能的确切位置.如果在 render 方法中使用了 Arrow function,那么它们会创建一个新实例 everytime render 被调用,就像 bind 的工作方式一样.考虑这个例子

This is not true. It depends on where exactly are you using the Arrow function. If Arrow function are used in render method, then they create a new instance everytime render is called just like how bind would work. Consider this example

<div onClick={()=>{this.onClick()}}>Previous</div>

这里每次调用 render 时都会创建一个匿名函数,调用该函数时会调用 this.onClick.

Here each time render is called an anonymous function is created and that function when called, calls this.onClick.

但是考虑下面的情况

onClick = () => {
    console.log("Div is clicked")
}

在上述情况下,箭头函数不会每次都重新创建函数,而是将上下文绑定到 React 组件,因为 箭头函数没有自己的 this;使用封闭执行上下文的 this 值. 实例化类时使用一次.这类似于 binding 的工作原理是 constructor.这是 proposed class fields for arrow functions 的一部分,它不是 ES6 特性,

In above case, the arrow function does not recreate function everytime, but binds the context to the React component as An arrow function does not have its own this; the this value of the enclosing execution context is used. once when the class is instantiated. This is similar to how binding works is constructor. This is a part of proposed class fields for arrow functions and it isn't a ES6 feature,

要理解你想问什么,你必须知道一个函数从它被调用的地方获取它的上下文.检查这个问题 了解更多.

To understand what you wish to ask, you must know that a function gets its context from where it is called. Check this question for more understanding.

在你的例子中,你已经使用 Arrow function 来定义 prevItem 并且因此它获得了封闭的 React 组件的上下文.

In your case, you have used Arrow function to define prevItem and hence it gets the context of the enclosing React component.

prevItem = () => {
    console.log("Div is clicked")
}

render(){
    return (
         <SecondClass prevItem={this.prevItem} />
    )
}

现在在它的子级中,即使您使用任何自定义上下文调用 prevItem使用绑定或箭头函数prevItem 在父级中执行时即 Main.js 将获得其封闭的 React 组件的上下文.而且由于您只想执行 prevItem 函数并且不想将任何数据从孩子传递给它,因此编写

Now in its child, even if you call prevItem with any custom context, using bind or arrow function, prevItem when executed in parent i.e Main.js will get the context of its enclosing React component. And since you just wish to execute prevItem function and do not want to pass any data to this from the child, writing

<ThirdClass type="prev" onClick={()=>this.props.prevItem()} />

<div onClick={()=>{this.props.onClick()}}>Previous</div>

根本没用,只会增加性能影响,因为每次都会在 SecondClassThirdClass 中创建新函数.您根本不需要将这些函数定义为箭头函数,只需编写

is simply useless and will only add to performance implication since new functions are created in SecondClass and ThirdClass everytime. You simply don't need to have these functions defined as arrow function and could just write

<ThirdClass type="prev" onClick={this.props.prevItem} />

<div onClick={this.props.onClick}>Previous</div>

因为它已经绑定在父级中.

since its already binded in the parent.

现在即使你必须从 ThirdClass 和 SecondClass 向这些函数传递一些额外的数据,你也不应该直接使用 Arrow functionbind in render.在 如何避免绑定上查看此答案在渲染方法中

Now even if you have to pass some additional data to these function from ThirdClass and SecondClass, you shouldn't directly use Arrow function or bind in render. Have a look at this answer on How to Avoid binding in Render method

相关文章