React:哪个是推荐的箭头或正常功能?
React: Which is recommended arrow or normal function?
我开始使用箭头函数是因为我觉得手动 function/object 绑定和范围相关的问题很头疼,但最近我开始知道使用普通函数 (ES5) 比使用箭头函数 (ES6) 更好.
我对这些函数的理解
React 中的正常功能:
- Bind object/function manually in order to play with state or props inside the function and to avoid scope related issues
- Bind object/function always in constructor but not directly in render
- If you do it in constructor then Webpack creates new object/function in bundle.js file only once when your component renders for the first time
- If you do it directly in render then Webpack will create a new object/function in bundle.js file every time your component renders and re-renders
- If you don’t bind then you can’t access state or props. You have to assign current object to a local variable otherwise this.state or this.props is undefined
React 中的箭头函数:
- No need to bind an object/function in constructor nor render
- You no need to depend on local variable interms of current object i.e., let that = this;
- You will not have scope issues and object/function binding takes automatically
但我的疑问是,我听说建议使用普通函数并将其绑定在构造函数中,而不是使用箭头函数,因为每次你的组件时,箭头函数都会在 Webpack bundle.js 中创建新的 object/function渲染和重新渲染。
Is this true? Which is Recommended?
此线程接受的答案 说 —> 这取决于您使用箭头功能的确切位置。如果在 render 方法中使用 Arrow 函数,那么每次调用 render 时它们都会创建一个新实例,就像 bind 的工作方式一样。
对不起,如果你觉得这是一个戏剧性的问题,但这是我最大的疑问。请推荐
如果您有以下 React 代码,
class A extends React.Component {
constructor(props) {
super(props)
this.state = {name: props.name}
}
render() {
return (
<button onclick={(event)=>console.log(this.state.name)} />
)
}
}
改为关注
class A extends React.Component {
state = {name: this.props.name}
render() {
return (
<button onclick={this.logName} />
)
}
logName = (event) => {
console.log(this.state.name)
}
}
这样,您就不会在每次渲染时都创建新的匿名函数。
每次你有代码时都会创建新的函数实例 运行ning
()=>
,这不是magic
。看看下面的成员函数
class A {
memberFuncWithBinding = () => {}
memberFuncWithoutBinding(){}
}
这两个成员函数只在 class 实例化时创建一次。同样,没有魔法,但是上层成员函数是首选,因为在该函数内部使用 this
时,您将拥有正确的 class A this 绑定。
编辑:看,在 运行 遇到问题之前不要尝试优化代码。每次渲染创建新函数都比较慢,但只有几分之一毫秒。
周围有很多答案,但人们总是感到困惑。我知道这一点,因为我前一段时间感到困惑。一段时间后,我掌握了这些概念。
- Bind object/function manually in order to play with state or props
inside the function and to avoid scope-related issues
不完全正确。您无需绑定函数即可使用状态或道具。当您在作用域中丢失 this
上下文时,您将函数绑定到 this
。例如在回调函数中。
class App extends React.Component {
state = {
name: "foo",
}
aFunction() {
console.log( this.state.name );
}
render() {
return <div>{this.aFunction()}</div>;
}
}
您不需要绑定您的函数,因为 this
指向您的 class 并且您不会丢失它的上下文。但是如果你像按钮一样在回调中使用你的函数,你必须绑定它:
class App extends React.Component {
state = {
name: "foo",
}
aFunction() {
console.log( this.state.name );
}
render() {
return (
<div>
<button onClick={this.aFunction}>Click</button>
</div>
);
}
}
这不起作用,因为您失去了上下文。现在,您需要以某种方式取回它的上下文吗?好的,让我们看看我们如何做到这一点。首先,我想在按钮回调中绑定它。
<button onClick={this.aFunction.bind(this)}>Click</button>
是的,这行得通。但是,它将在每次渲染中重新创建。所以:
- Bind object/function always in constructor but not directly in render
是的。不要像我上面那样绑定它,在你的构造函数中做。
If you do it in constructor then Webpack creates new object/function in bundle.js file only once when your component
renders for the first time
If you do it directly in render then Webpack will create a new object/function in bundle.js file every time your component renders
and re-render
你在这里总结了我迄今为止试图解释的内容。但是,我想 Webpack 不是这样做的,你的应用程序是。
- If you don’t bind then you can’t access state or props. You have to assign current object to a local variable otherwise this.state or
this.props is undefined
同样,如果您在 class 范围内使用函数,则不必绑定它。如果您在 class 之外使用此功能,例如按钮回调,则必须绑定它。这与 state
或 props
无关。这与使用 this
有关。
您的第二个绑定选项是使用常规函数在构造函数中进行绑定,第三个选项是使用不带绑定的箭头函数。
现在,箭头函数。
1.No need to bind an object/function in constructor nor render
是的。
- You no need to depend on local variable interms of current object i.e., let that = this;
是的。
- You will not have scope issues and object/function binding takes automatically
是的。
But my query is that I heard that it’s recommended to use normal
function and bind it in constructor rather than using arrow function
because arrow functions create new object/function in Webpack
bundle.js every time your component renders & re-renders.
正如大家所说,这取决于你在哪里使用它们。
render() {
return (
<div>
<button onClick={() => this.aFunction()}>Click</button>
</div>
);
}
在这里,它将在每次渲染中重新创建。但是如果你不需要传递任何参数给它,你可以通过引用使用它。
render() {
return (
<div>
<button onClick={this.aFunction}>Click</button>
</div>
);
}
这与上一个一样。因此,如果您在渲染方法中看到 ()
,则该函数会在每次渲染中重新创建。常规或箭头一,没关系。如果您以某种方式调用它,那么您就是在重新创建它。这适用于像 aFunction.bind(this)
这样的渲染中的绑定。我在那里看到 ()
。
所以,通过引用使用函数可以避免这个问题。现在,最大的问题是当我们需要一些参数时会发生什么?如果您使用箭头函数传递参数,请尝试更改您的逻辑。
但这真的那么重要吗?正如@Eric Kim 所说,如果您确实需要优化,那么优化就是一个问题。这是一个普遍的建议,因为我从很多人那里听说过。但就个人而言,如果函数将在每次渲染中重新创建,我会尽量避免使用它们。但同样,这完全是个人的。
你怎么能改变你的逻辑?您正在用一个项目映射一个数组并创建
一个按钮。在此按钮中,您使用的是将项目名称传递给函数的函数。
{
items.map( item =>
<button onClick={() => this.aFunction(item.name)}>Click</button>
)
}
此函数将在每个项目的每次渲染中重新创建!所以,改变你的逻辑,创建一个单独的 Item
组件并映射它。将 item
、aFunction
作为 props 传递。然后在这个组件中使用处理函数使用你的函数。
const Item = ( props ) => {
const handleClick = () => props.aFunction( props.item.name );
return (
<button onClick={handleClick}>Click</button>
);
}
在这里,您使用的是 onClick
处理程序及其引用,它会调用您的实际函数。不会在每次渲染中重新创建函数。但是,不利的是,您需要编写一个单独的组件和更多的代码。
大多数时候您都可以应用此逻辑。也许会有一些你做不到的例子,谁知道呢。所以决定权在你。
顺便说一句,@widged 在评论中给出的 Medium post 是关于这个问题的著名讨论。箭头函数真的比普通函数慢吗?是的。但是多少钱?我猜没那么多。此外,对于转译后的代码也是如此。以后变成原生的时候,就是速度更快的了。
作为个人旁注。我一直在使用箭头函数,因为我喜欢它们。不过前段时间在讨论中,有人说
When I see an arrow function in the class I think that: 'This function
is being used/called outside of this class'. If I see a regular one I
understand that this function called inside the class.
我真的很喜欢这种方法,现在如果我不需要在 class 之外调用我的函数,我会使用常规方法。
我开始使用箭头函数是因为我觉得手动 function/object 绑定和范围相关的问题很头疼,但最近我开始知道使用普通函数 (ES5) 比使用箭头函数 (ES6) 更好.
我对这些函数的理解
React 中的正常功能:
- Bind object/function manually in order to play with state or props inside the function and to avoid scope related issues
- Bind object/function always in constructor but not directly in render
- If you do it in constructor then Webpack creates new object/function in bundle.js file only once when your component renders for the first time
- If you do it directly in render then Webpack will create a new object/function in bundle.js file every time your component renders and re-renders
- If you don’t bind then you can’t access state or props. You have to assign current object to a local variable otherwise this.state or this.props is undefined
React 中的箭头函数:
- No need to bind an object/function in constructor nor render
- You no need to depend on local variable interms of current object i.e., let that = this;
- You will not have scope issues and object/function binding takes automatically
但我的疑问是,我听说建议使用普通函数并将其绑定在构造函数中,而不是使用箭头函数,因为每次你的组件时,箭头函数都会在 Webpack bundle.js 中创建新的 object/function渲染和重新渲染。
Is this true? Which is Recommended?
此线程接受的答案
对不起,如果你觉得这是一个戏剧性的问题,但这是我最大的疑问。请推荐
如果您有以下 React 代码,
class A extends React.Component {
constructor(props) {
super(props)
this.state = {name: props.name}
}
render() {
return (
<button onclick={(event)=>console.log(this.state.name)} />
)
}
}
改为关注
class A extends React.Component {
state = {name: this.props.name}
render() {
return (
<button onclick={this.logName} />
)
}
logName = (event) => {
console.log(this.state.name)
}
}
这样,您就不会在每次渲染时都创建新的匿名函数。
每次你有代码时都会创建新的函数实例 运行ning
()=>
,这不是magic
。看看下面的成员函数
class A {
memberFuncWithBinding = () => {}
memberFuncWithoutBinding(){}
}
这两个成员函数只在 class 实例化时创建一次。同样,没有魔法,但是上层成员函数是首选,因为在该函数内部使用 this
时,您将拥有正确的 class A this 绑定。
编辑:看,在 运行 遇到问题之前不要尝试优化代码。每次渲染创建新函数都比较慢,但只有几分之一毫秒。
周围有很多答案,但人们总是感到困惑。我知道这一点,因为我前一段时间感到困惑。一段时间后,我掌握了这些概念。
- Bind object/function manually in order to play with state or props inside the function and to avoid scope-related issues
不完全正确。您无需绑定函数即可使用状态或道具。当您在作用域中丢失 this
上下文时,您将函数绑定到 this
。例如在回调函数中。
class App extends React.Component {
state = {
name: "foo",
}
aFunction() {
console.log( this.state.name );
}
render() {
return <div>{this.aFunction()}</div>;
}
}
您不需要绑定您的函数,因为 this
指向您的 class 并且您不会丢失它的上下文。但是如果你像按钮一样在回调中使用你的函数,你必须绑定它:
class App extends React.Component {
state = {
name: "foo",
}
aFunction() {
console.log( this.state.name );
}
render() {
return (
<div>
<button onClick={this.aFunction}>Click</button>
</div>
);
}
}
这不起作用,因为您失去了上下文。现在,您需要以某种方式取回它的上下文吗?好的,让我们看看我们如何做到这一点。首先,我想在按钮回调中绑定它。
<button onClick={this.aFunction.bind(this)}>Click</button>
是的,这行得通。但是,它将在每次渲染中重新创建。所以:
- Bind object/function always in constructor but not directly in render
是的。不要像我上面那样绑定它,在你的构造函数中做。
If you do it in constructor then Webpack creates new object/function in bundle.js file only once when your component renders for the first time
If you do it directly in render then Webpack will create a new object/function in bundle.js file every time your component renders and re-render
你在这里总结了我迄今为止试图解释的内容。但是,我想 Webpack 不是这样做的,你的应用程序是。
- If you don’t bind then you can’t access state or props. You have to assign current object to a local variable otherwise this.state or this.props is undefined
同样,如果您在 class 范围内使用函数,则不必绑定它。如果您在 class 之外使用此功能,例如按钮回调,则必须绑定它。这与 state
或 props
无关。这与使用 this
有关。
您的第二个绑定选项是使用常规函数在构造函数中进行绑定,第三个选项是使用不带绑定的箭头函数。
现在,箭头函数。
1.No need to bind an object/function in constructor nor render
是的。
- You no need to depend on local variable interms of current object i.e., let that = this;
是的。
- You will not have scope issues and object/function binding takes automatically
是的。
But my query is that I heard that it’s recommended to use normal function and bind it in constructor rather than using arrow function because arrow functions create new object/function in Webpack bundle.js every time your component renders & re-renders.
正如大家所说,这取决于你在哪里使用它们。
render() {
return (
<div>
<button onClick={() => this.aFunction()}>Click</button>
</div>
);
}
在这里,它将在每次渲染中重新创建。但是如果你不需要传递任何参数给它,你可以通过引用使用它。
render() {
return (
<div>
<button onClick={this.aFunction}>Click</button>
</div>
);
}
这与上一个一样。因此,如果您在渲染方法中看到 ()
,则该函数会在每次渲染中重新创建。常规或箭头一,没关系。如果您以某种方式调用它,那么您就是在重新创建它。这适用于像 aFunction.bind(this)
这样的渲染中的绑定。我在那里看到 ()
。
所以,通过引用使用函数可以避免这个问题。现在,最大的问题是当我们需要一些参数时会发生什么?如果您使用箭头函数传递参数,请尝试更改您的逻辑。
但这真的那么重要吗?正如@Eric Kim 所说,如果您确实需要优化,那么优化就是一个问题。这是一个普遍的建议,因为我从很多人那里听说过。但就个人而言,如果函数将在每次渲染中重新创建,我会尽量避免使用它们。但同样,这完全是个人的。
你怎么能改变你的逻辑?您正在用一个项目映射一个数组并创建 一个按钮。在此按钮中,您使用的是将项目名称传递给函数的函数。
{
items.map( item =>
<button onClick={() => this.aFunction(item.name)}>Click</button>
)
}
此函数将在每个项目的每次渲染中重新创建!所以,改变你的逻辑,创建一个单独的 Item
组件并映射它。将 item
、aFunction
作为 props 传递。然后在这个组件中使用处理函数使用你的函数。
const Item = ( props ) => {
const handleClick = () => props.aFunction( props.item.name );
return (
<button onClick={handleClick}>Click</button>
);
}
在这里,您使用的是 onClick
处理程序及其引用,它会调用您的实际函数。不会在每次渲染中重新创建函数。但是,不利的是,您需要编写一个单独的组件和更多的代码。
大多数时候您都可以应用此逻辑。也许会有一些你做不到的例子,谁知道呢。所以决定权在你。
顺便说一句,@widged 在评论中给出的 Medium post 是关于这个问题的著名讨论。箭头函数真的比普通函数慢吗?是的。但是多少钱?我猜没那么多。此外,对于转译后的代码也是如此。以后变成原生的时候,就是速度更快的了。
作为个人旁注。我一直在使用箭头函数,因为我喜欢它们。不过前段时间在讨论中,有人说
When I see an arrow function in the class I think that: 'This function is being used/called outside of this class'. If I see a regular one I understand that this function called inside the class.
我真的很喜欢这种方法,现在如果我不需要在 class 之外调用我的函数,我会使用常规方法。