如何避免render方法中的bind或inline箭头函数 [英] How to avoid bind or inline arrow functions inside render method

查看:114
本文介绍了如何避免render方法中的bind或inline箭头函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们应该避免在渲染中绑定方法,因为在重新渲染期间它会创建新方法而不是使用旧方法,这会影响性能。

We should avoid method binding inside render because during re-rendering it will create the new methods instead of using the old one, that will affect the performance.

所以对于这样的场景:

<input onChange = { this._handleChange.bind(this) } ...../>

我们可以在构造函数中绑定 _handleChange 方法:

We can bind _handleChange method either in constructor:

this._handleChange = this._handleChange.bind(this);

或者我们可以使用属性初始化语法

_handleChange = () => {....}

现在让我们考虑一下我们想传递一些额外参数的情况,让在一个简单的待办事项应用程序中,我需要从数组中删除项目,因为我需要在每个onClick方法中传递项目索引或待办事项名称:

Now lets consider the case where we want to pass some extra parameter, lets say in a simple todo app, onclick of item i need to delete the item from array, for that i need to pass either the item index or the todo name in each onClick method:

todos.map(el => <div key={el} onClick={this._deleteTodo.bind(this, el)}> {el} </div>)

现在假设todo名称是唯一的。

For now just assume that todo names are unique.

根据 DOC


这种语法的问题是每次组件渲染时都会创建一个不同的回调

The problem with this syntax is that a different callback is created each time the component renders.

问题:

如何避免这种方式内部渲染方法中的绑定或其替代方法是什么?

How to avoid this way of binding inside render method or what are the alternatives of this?

请提供任何参考o例如,谢谢。

Kindly provide any reference or example, thanks.

推荐答案

首先:一个简单的解决方案是为其创建一个组件map函数中的内容并将值作为props传递,当您从子组件调用该函数时,您可以将值传递给作为props传递的函数。

First: A simple solution will be to create a component for the content inside a map function and pass the values as props and when you call the function from the child component you can pass the value to the function passed down as props.

父母

deleteTodo = (val) => {
    console.log(val)
}
todos.map(el => 
    <MyComponent val={el} onClick={this.deleteTodo}/> 

)

MyComponent

class MyComponent extends React.Component {
    deleteTodo = () => {
        this.props.onClick(this.props.val);
    }
    render() {
       return <div  onClick={this.deleteTodo}> {this.props.val} </div>
    }
}

示例代码段

class Parent extends React.Component {
     _deleteTodo = (val) => {
        console.log(val)
    }
    render() {
        var todos = ['a', 'b', 'c'];
        return (
           <div>{todos.map(el => 
             <MyComponent key={el} val={el} onClick={this._deleteTodo}/> 
        
           )}</div>
        )
    }
    
   
}

class MyComponent extends React.Component {
        _deleteTodo = () => {
                     console.log('here');   this.props.onClick(this.props.val);
        }
        render() {
           return <div onClick={this._deleteTodo}> {this.props.val} </div>
        }
    }
    
ReactDOM.render(<Parent/>, document.getElementById('app'));

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>

编辑:

第二:另一种方法是使用memoize并返回一个函数

Second: The other approach to it would be to use memoize and return a function

constructor() {
    super();
    this._deleteTodoListener = _.memoize(
                   this._deleteTodo, (element) => {
                        return element.hashCode();
                    }
              )
}

_deleteTodo = (element) => {
   //delete handling here
}

并使用它像

todos.map(el => <div key={el} onClick={this._deleteTodoListener(el)}> {el} </div>)




PS然而,这不是一个最好的解决方案,仍然会导致
创建多个函数,但仍然比
初始案例有所改进。

P.S. However this is not a best solution and will still result in multiple functions being created but is still an improvement over the initial case.

第三:然而,对此更合适的解决方案是将属性添加到最顶层的div并获取值来自事件喜欢

Third: However a more appropriate solution to this will be to add an attribute to the topmost div and get the value from event like

_deleteTodo = (e) => {
     console.log(e.currentTarget.getAttribute('data-value'));

 }

 todos.map(el => <div key={el} data-value={el} onClick={this._deleteTodo}> {el} </div>)

但是,在这种情况下,使用toString将属性转换为字符串方法,因此和对象将转换为 [Object Object] 和数组,如 [1,2,3] as 1,2,3

However, in this case the attributes are converted to string using toString method and hence and object will be converted to [Object Object] and and array like ["1" , "2", "3"] as "1, 2, 3"

这篇关于如何避免render方法中的bind或inline箭头函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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