javascript - React 最佳实践:如果我们不能在 JSX onChange() 中使用箭头函数,我们如何传入自定义参数?
问题描述
我正在寻找 React 组件中箭头函数的优雅替代方案。
显然在 React
中,在父容器中使用箭头函数会导致子容器的性能问题。这是因为匿名箭头函数被认为是“新”函数实例,所以每个父render()
级都会导致纯组件重新渲染(如果所述箭头函数被向下传递)。
我个人喜欢使用箭头函数的可读性。以下面的代码为例:
render() {
return (
<div>
<h1>Users</h1>
<ul>
{this.state.users.map(user => {
return (
<User key={user.id} user={user} onClick={(e) => this.deleteUser(e, user.id)} />;
)
}}
</ul>
</div>
);
}
很清楚this.deleteUser()
它的论点从何而来。但是将其与“应该完成”的方式进行比较:
import React from 'react';
import { render } from 'react-dom';
import User from './User';
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
users: [
{ id: 1, name: 'Cory' },
{ id: 2, name: 'Meg' },
{ id: 3, name: 'Bob'}
],
};
}
deleteUser = id => {
this.setState(prevState => {
return {
users: prevState.users.filter(user => user.id !== id)
};
});
};
renderUser = user => {
return <User key={user.id} user={user} onClick={this.deleteUser} />;
}
render() {
return (
<div>
<h1>Users</h1>
<ul>
{this.state.users.map(this.renderUser)}
</ul>
</div>
);
}
}
render(<App />, document.getElementById('root'));
为什么??这可读性要差得多。你怎么知道作为参数传入this.renderUser
?user
你怎么知道作为参数传入this.deleteUser
?userId
有哪些选择?一个现有的stackoverflow 问题建议将子组件移动到他们自己的组件中并通过 props 传递参数,但有时您不想变得如此模块化。
没有像箭头函数一样优雅的理智解决方案吗?还是我们最好的希望是等到 React 团队为了可读性和社区采用而修补这个?
解决方案
你怎么知道 this.renderUser 获取用户作为参数传入?你怎么知道 this.deleteUser 获取 userId 作为参数传入?
让我们举个this.state.users.map(this.renderUser)
例子。如您所知,您this.state.users
是一个数组。这表明这map
是Array.map函数。函数签名看起来像这样(简化形式)
someArray.map(currentItem => {
// Handle your item here
});
如您所见,它需要回调。该回调本身最多可以接受 3 个参数(我们这里只需要一个)。现在回头看看你的this.renderUser
,我们可以看到它也是一个接受一个参数的函数。
然后我们可以将它用作我们之前map
函数的回调。如果我们只是复制/粘贴它的实现,我们将有这样的东西
this.state.users.map(user => {
return <User key={user.id} user={user} onClick={this.deleteUser} />;
});
因此,当您编写 时this.state.users.map(this.renderUser)
,您所做的事情就像复制/粘贴您的函数一样。user
两种情况下的论点相同
推荐阅读
- javascript - 在浏览器上使用 Processing.js 播放声音
- python - 如何根据列的值拆分决策树
- android - Kotlin 错误 - 委托调用链中有一个循环
- r - R - 通过值计数识别固定宽度的范围
- python - PySimpleGUI RELIEF_SUNKEN 在项目标记为可见时扩展,但在项目标记为不可见时不收缩
- rust - 了解 Rust 和类型系统
- java - 从哈希图中,如何将不同的值替换为输入句子中出现的每个“键”?
- javascript - bootstrap vue 模态黑色背景
- sql-server - SQL Server 查找索引定义
- swift - 尝试从手册编译 Swift 代码时出现错误:“类型不符合协议‘Comparable’”