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

所以对于这样的场景:

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

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

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

或者我们可以使用property initializer syntax:

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

现在让我们考虑一下我们想传递一些额外参数的情况,让我们在一个简单的ToDo应用程序中,点击OnCutter,我需要从数组中删除这个项目,因为我需要在每个OnCutt方法中传递项目索引或todo-Node:

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

现在只需假设todo名称是唯一的.

根据DOC:

这种语法的问题是创建了不同的回调

Question:

如何避免这种在渲染方法内部绑定的方式,或者有什么替代方法?

请提供任何参考或例子,谢谢.

推荐答案

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

Parent

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>

EDIT:

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

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>)

但是,这不是一个最佳解决方案,仍然会导致

Third:然而,一个更合适的解决方案是在最顶端的div上加一个attribute,然后从event中得到值

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

 }

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

然而,在这种情况下,属性将使用toString方法转换为字符串,因此and object将被转换为[Object Object]和数组,比如["1" , "2", "3"]"1, 2, 3"

Reactjs相关问答推荐

react-native-markdown-显示样式表

运行 node server.js会导致以下错误:Route.post()需要回调函数,但在Route.&处得到了[对象Undefined] lt;计算>

从另一个组件更改组件中const的状态

后端关闭时如何在REACTION AXIOS拦截器中模拟数据?

有没有办法让两个状态在两次精准渲染中更新?

我想删除NextJs中的X轴标签APEXCHARTS

react 路由GUGUD Use Effect无法通过useNavigate正常工作

无法将react 路由状态从路由传递给子组件

在Reaction中的第一次装载时,Use Effect返回空数组

useEffect firebase 清理功能如何工作?

在 React 中将 MUI 样式外包到单独的文件中?

如何在next.js 13中仅在主页导航栏上隐藏组件?

如何在屏幕上使用相同的可重用

在react 中从外部 api 渲染列表

需要在窗口调整大小时更新 React 组件

在 Spring Cloud Gateway 中运行的 React SPA 页面刷新出现白标错误

如何禁用来自 React Native API 的某些特定项目的可touch 不透明度

如何使图标适合 react-bootstrap 中的行元素

理解 React 中的 PrevState

如何将本地视频文件上传到 Google Cloud