反应:建议使用哪个箭头或正常功能? [英] React: Which is recommended arrow or normal function?

查看:54
本文介绍了反应:建议使用哪个箭头或正常功能?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我感到手工功能/对象绑定以及与范围相关的问题让人头疼之后,我开始使用箭头功能,但是非常有意思的是,我开始知道使用正常功能(ES5)比使用箭头功能(ES6)更好.

I started using arrow functions after I felt doing manual function/object bindings and scope related issues are headache but very rencently I came to know that it’s better to use normal function(ES5) than arrow function(ES6).

我对这些功能的理解

React中的正常功能:

Normal function in React:

  1. 手动绑定对象/功能,以便在功能内部玩状态或道具并避免与范围相关的问题
  2. 总是在构造函数中绑定对象/函数,而不是直接在渲染中绑定
  3. 如果您在构造函数中执行此操作,则Webpack仅在组件首次呈现时在bundle.js文件中创建一次新的对象/函数
  4. 如果直接在渲染中进行操作,则每次组件渲染并重新渲染时,Webpack都会在bundle.js文件中创建一个新的对象/函数
  5. 如果您不绑定,则无法访问状态或道具.您必须将当前对象分配给局部变量,否则this.state或this.props未定义
  1. Bind object/function manually in order to play with state or props inside the function and to avoid scope related issues
  2. Bind object/function always in constructor but not directly in render
  3. 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
  4. 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
  5. 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中的箭头功能:

Arrow function in React:

  1. 无需在构造函数中绑定对象/函数也无需渲染
  2. 您无需依赖当前对象的局部变量项,即让它= this;
  3. 您将不会遇到范围问题,并且对象/函数绑定会自动出现
  1. No need to bind an object/function in constructor nor render
  2. You no need to depend on local variable interms of current object i.e., let that = this;
  3. You will not have scope issues and object/function binding takes automatically

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

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.

这是真的吗?推荐哪个?

Is this true? Which is Recommended?

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

This thread accepted answer Correct use of arrow functions in React says —> It depends on where exactly are you using the Arrow function. If Arrow function are used in render method, then they creates a new instance everytime render is called just like how bind would work.

很抱歉,如果您觉得这是一个戏剧问题,但这是我最大的疑问.请建议

Sorry if you feel it’s a theatrical question but this is my biggest doubt. Kindly suggest

推荐答案

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

There are so many answers around there but people always get confused. I know this because I got confused once a while ago. After some time, I grasped the concepts.

  1. 手动绑定对象/功能,以便与状态或道具一起玩 函数内部,并避免与范围相关的问题
  1. Bind object/function manually in order to play with state or props inside the function and to avoid scope-related issues

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

Not exactly true. You don't need to bind the functions to play with state or props. You bind the function to this when you lose this context in the scope. For example in a callback function.

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

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

You don't need to bind your function since this points your class and you don't lose its context. But if you use your function in a callback like a button, you have to bind it:

class App extends React.Component {
  state = {
    name: "foo",
  }
  aFunction() {
    console.log( this.state.name );
  }

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

这不起作用,因为您丢失了上下文.现在,您需要以某种方式重新获得其上下文?好的,让我们看看如何做到这一点.首先,我想将其绑定到按钮回调中.

This does not work since you lose the context. Now, you need to get its context back somehow right? Ok, let's see how we can do this. First, I want to bind it in the button callback.

<button onClick={this.aFunction.bind(this)}>Click</button>

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

Yeah, this works. But, it will be recreated in every render. So:

  1. 总是在构造函数中绑定对象/函数,而不是直接在渲染中绑定

是的.不要像我上面那样绑定它,而是在您的构造函数中完成它.

Yes. Do not bind it like I did above, do it in your constructor.

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

  1. 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

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

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不是这样做的,您的App是这样的.

You are summarizing here what I've tried to explain up to now. But, I suppose Webpack is not the one doing this, your App is.

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

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

Again, if you use your function inside your class scope, you don't have to bind it. If you use this function outside of your class, like a button callback, you have to bind it. This is not related to state or props. This is related to using this.

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

Your second option for binding is doing the binding in the constructor by using a regular function and the third one is using an arrow function without binding.

现在,箭头功能.

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

1.No need to bind an object/function in constructor nor render

是的

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

是的

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

是的

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

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.

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

Like everybody said, that depends on where you use them.

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

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

Here, it will be recreated in every render. But if you don't need to pass any argument to it, you can use it by reference.

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

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

This works as the previous one. So, if you see a () in your render method, this function recreated in every render. Regular or an arrow one, doesn't matter. If you are invoking it somehow, then you are recreating it. This applies to bind in the render like aFunction.bind(this). I see () there.

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

So, use functions by their references to avoid this issue. Now, the big question is what happens when we need some arguments? If you use an arrow function to pass an argument then try to change your logic.

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

But is it really important as much? Like @Eric Kim said, optimizing is an issue if you really need it. This is a general suggestion since I've heard this from lots of people. But personally, I am trying to avoid using functions if they will be recreated in every render. But again, this is totally personal.

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

How can you change your logic? You are mapping over an array with an item and creating a button. In this button, you are using a function that passes item's name to a function.

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

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

This function will be recreated in every render for each item! So, change your logic, create a separate Item component and map it. Pass the item, aFunction as props. Then with a handler function in this component use your function.

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

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

Here, you are using an onClick handler with its reference and it invokes your real function. No function will be recreated in every render. But, as a downside, you need to write a separate component and a little bit more code.

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

You can apply this logic most of the time. Maybe there will be some examples you can't, who knows. So the decision is yours.

顺便说一句,@ widged在评论中给出的中型帖子是有关此问题的著名讨论.箭头功能真的比常规功能慢吗?是的.但是多少钱?我猜没有那么多.同样,对于已编译的代码也是如此.将来,当它们变得原生时,它们将是更快的.

By the way, the Medium post that @widged gave in the comments is a famous discussion about this issue. Are arrow functions really slower than the regular ones? Yes. But how much? Not so much I guess. Also, this is true for transpiled code. In the future when they become native, then they will be the faster ones.

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

As a personal side note. I was using arrow functions all the time since I like them. But a while ago in a discussion, someone said

当我在课堂上看到箭头功能时,我认为:'此功能 在此类之外被使用/调用".如果我看到一个普通的我 了解此函数在类内部调用.

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.

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

I really liked this approach and now if I don't need to call my function outside of my class I am using a regular one.

这篇关于反应:建议使用哪个箭头或正常功能?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆