小编典典

React:推荐使用箭头还是正常功能?

reactjs

在感到手动功能/对象绑定以及与范围相关的问题令人头疼之后,我开始使用箭头功能,但非常清楚的是,我知道使用正常功能(ES5)比使用箭头功能(ES6)更好。

我对这些功能的理解

React中的正常功能:

  1. 手动绑定对象/功能,以便在功能内玩状态或道具并避免与范围相关的问题
  2. 始终在构造函数中绑定对象/函数,但不直接在渲染中
  3. 如果在构造函数中执行此操作,则Webpack仅在组件首次呈现时在bundle.js文件中创建一次新的对象/函数
  4. 如果直接在渲染中执行,则每次组件渲染并重新渲染时,Webpack都会在bundle.js文件中创建一个新的对象/函数
  5. 如果不绑定,则无法访问状态或道具。您必须将当前对象分配给局部变量,否则this.state或this.props未定义

React中的箭头功能:

  1. 无需在构造函数中绑定对象/函数也无需渲染
  2. 您无需依赖当前对象的局部变量项,即,使= this;
  3. 您不会遇到范围问题,并且对象/函数绑定会自动进行

但是我的查询是,我听说建议使用常规函数并将其绑定到构造函数中,而不要使用arrow函数,因为每次组件渲染和重新渲染时,箭头函数都会在Webpack
bundle.js中创建新的对象/函数。

这是真的?哪个推荐?

这个线程接受了答案React中正确使用箭头函数说->这取决于您在哪里使用了箭头函数。如果在render方法中使用了Arrow函数,则每次调用render时,它们都会创建一个新实例,就像bind如何工作一样。

抱歉,如果您认为这是一个戏剧问题,但这是我最大的疑问。请建议


阅读 285

收藏
2020-07-22

共1个答案

小编典典

那里有很多答案,但人们总是感到困惑。我知道这一点是因为我前一段时间感到困惑。一段时间后,我掌握了这些概念。

  1. 手动绑定对象/功能,以便在功能内玩状态或道具并避免与范围相关的问题

不完全正确。您无需绑定功能即可与状态或道具一起玩。this当您this在范围中丢失上下文时,可以将函数绑定到。例如在回调函数中。

class App extends React.Component {
  state = {
    name: "foo",
  }
  aFunction() {
    console.log( this.state.name );
  }
  render() {
    return <div>{this.aFunction()}</div>;
  }
}

因为this指向了类,所以您不需要绑定函数,并且不会丢失其上下文。但是,如果您在按钮之类的回调中使用函数,则必须将其绑定:

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>

是的,这可行。但是,它将在每个渲染中重新创建。所以:

  1. 始终在构造函数中绑定对象/函数,但不直接在渲染中

是。不要像上面那样绑定它,而是在您的构造函数中进行。

  1. 如果在构造函数中执行此操作,则Webpack仅在组件首次呈现时在bundle.js文件中创建一次新的对象/函数

  2. 如果直接在渲染中执行,则每次组件渲染并重新渲染时,Webpack都会在bundle.js文件中创建一个新的对象/函数

您在这里总结了到目前为止我一直在尝试解释的内容。但是,我想Webpack不是这样做的,您的App是。

  1. 如果不绑定,则无法访问状态或道具。您必须将当前对象分配给局部变量,否则this.state或this.props未定义

同样,如果您在类范围内使用函数,则不必绑定它。如果在类之外使用此函数(例如按钮回调),则必须将其绑定。这与state或无关props。这与使用有关this

绑定的第二个选项是使用常规函数在构造函数中进行绑定,而第三个选项是使用无绑定的箭头函数。

现在,箭头功能。

1,无需在构造函数中绑定对象/函数或渲染

是。

  1. 您无需依赖当前对象的局部变量项,即,使= this;

是。

  1. 您不会遇到范围问题,并且对象/函数绑定会自动进行

是。

但是我的查询是,我听说建议使用常规函数并将其绑定到构造函数中,而不要使用arrow函数,因为每次组件渲染和重新渲染时,箭头函数都会在Webpack
bundle.js中创建新的对象/函数。

就像每个人都说的那样,这取决于您在哪里使用它们。

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

在这里,它将在每个渲染中重新创建。但是,如果您不需要传递任何参数,则可以通过引用使用它。

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

这与上一个相同。因此,如果()在render方法中看到一个,则在每个渲染中都会重新创建此函数。常规或箭头一无所谓。如果您以某种方式调用它,那么您正在重新创建它。这适用于绑定到render之类的aFunction.bind(this)。我()在那里

因此,请按其引用使用函数,以避免出现此问题。现在,最大的问题是,当我们需要一些论点时会发生什么?如果使用箭头函数传递参数,请尝试更改逻辑。

但这真的很重要吗?就像@Eric
Kim所说的那样,如果您确实需要优化,则是一个问题。这是一个普遍的建议,因为我已经从很多人那里听到过。但就我个人而言,如果要在每个渲染器中重新创建函数,我将尽量避免使用它们。但是,这完全是个人的。

您如何更改逻辑?您正在映射带有项的数组并创建一个按钮。在此按钮中,您正在使用将项目名称传递给函数的函数。

{
    items.map( item =>
        <button onClick={() => this.aFunction(item.name)}>Click</button>
    )
}

将在每个项目的每个渲染中重新创建此功能!因此,更改您的逻辑,创建一个单独的Item组件并进行映射。通过itemaFunction作为道具。然后在该组件中使用处理程序函数,使用您的函数。

const Item = ( props ) => {
    const handleClick = () => props.aFunction( props.item.name );
    return (
        <button onClick={handleClick}>Click</button>
    );
}

在这里,您正在使用onClick带有其引用的处理程序,它会调用您的真实函数。在每个渲染中均不会重新创建任何功能。但是,不利的一面是,您需要编写一个单独的组件和更多代码。

您通常可以应用此逻辑。也许会有一些你不知道的例子,谁知道。因此,决定权由您决定。

顺便说一句,@
widged在评论中发表的Medium帖子是有关此问题的著名讨论。箭头功能真的比常规功能慢吗?是。但是多少钱?我猜没有那么多。同样,对于已编译的代码也是如此。将来,当他们成为本地人时,他们将成为更快的人。

作为个人说明。自从我喜欢箭头功能以来,我一直都在使用它们。但是不久前在讨论中,有人说

当我在该类中看到一个箭头函数时,我会认为:“此函数在该类外部被使用/调用”。如果我看到一个普通的函数,我知道该函数在类内部调用。

我真的很喜欢这种方法,现在,如果不需要在类之外调用函数,我将使用常规方法。

2020-07-22