通过重构 React 组件来学习公共类字段语法
阅读 React 代码时,你会遇到许多实现相同功能的不同方法。对于初学者来说,这很容易让人感到困惑。你可能会看到的一个区别是 React 类组件使用公共类字段语法。
这种语法并非 React 特有,而是可以用于编写任何 JavaScript 类。在深入探讨之前,需要注意的是,公共和私有类字段声明目前仍处于 TC39 流程的第三阶段。不过,可以通过 Babel 等构建系统来实现此功能(如果您正在编写 React 代码,则很可能已经在使用 Babel 了)。
我个人觉得,如果能看到代码经过多个步骤的重构过程,而不是仅仅看到初始版本和最终版本,就能更好地理解。我们有一个筹款组件,它包含一些状态并渲染两个组件。一个是表单,包含两个输入框,分别用于输入当前金额和目标金额;另一个用于显示这些数据。我们将重构这个组件,使其使用公共类字段语法。
以下是原始组件和最终组件,供您参考。
原装部件
import React from 'react';
import ProgressForm from './ProgressForm.js';
import ProgressBar from './ProgressBar.js';
class Fundraiser extends React.Component {
constructor(props) {
super(props);
this.handleAmountChange = this.handleAmountChange.bind(this);
this.handleGoalChange= this.handleGoalChange.bind(this);
this.state = { amount: '',
goal: ''
};
}
handleAmountChange(amount) {
this.setState({ amount });
}
handleGoalChange(goal) {
this.setState({ goal })
}
render() {
const { goal, amount } = this.state
return (
<>
<ProgressBar amount={amount} goal={goal} />
<ProgressForm
onAmountChange={this.handleAmountChange} amount={amount}
onGoalChange={this.handleGoalChange} goal={goal}
/>
</>
);
}
}
export default Fundraiser;
使用公共类字段语法重构
import React from 'react';
import ProgressForm from './ProgressForm.js';
import ProgressBar from './ProgressBar.js';
class Fundraiser extends React.Component {
state = { amount: '',
goal: ''
};
handleAmountChange = (amount) => {
this.setState({ amount });
}
handleGoalChange = (goal) => {
this.setState({ goal })
}
render() {
const { goal, amount } = this.state
return (
<>
<ProgressBar amount={amount} goal={goal} />
<ProgressForm
onAmountChange={this.handleAmountChange} amount={amount}
onGoalChange={this.handleGoalChange} goal={goal}
/>
</>
);
}
}
export default Fundraiser;
让我们看看发生了什么变化!
在我们的初始组件中,我们有一个类,其中包含一些事件处理程序的方法,handleAmountChange以及一个handleGoalChange方法render,constructor我们在其中设置一些状态,并处理正确的 this 绑定,以确保我们的方法能够按照预期的方式在正确的 this 上下文中工作。
我们首先可以轻松重构的地方是将状态变量从构造函数中移出。使用公共类字段语法,我们可以直接将其定义为类的属性或“字段”。
...
class Fundraiser extends React.Component {
constructor(props) {
super(props);
this.handleAmountChange = this.handleAmountChange.bind(this);
this.handleGoalChange= this.handleGoalChange.bind(this);
}
state = { amount: '',
goal: ''
};
...
现在构造函数中只剩下方法的 `this` 绑定了。我们可以通过将方法重构为箭头函数,将这些方法也从构造函数中移出来,这意味着我们可以完全移除构造函数!之所以能做到这一点,是因为箭头函数没有自己的this关键字,所以this关键字是按词法绑定的。
...
class Fundraiser extends React.Component {
state = { amount: '',
goal: ''
};
handleAmountChange = (amount) => {
this.setState({ amount });
}
handleGoalChange = (goal) => {
this.setState({ goal })
}
...
我们的代码现在看起来更易读,而且样板代码也更少了!
但是,我们可能并非总是想使用公共类字段语法……
编写代码时,我们总会面临各种权衡取舍。当向类中添加方法时,其底层原理与将该方法添加到函数原型中相同。当方法位于原型中时,无论创建多少个类实例,它都只会被定义一次。如果我们像上面那样使用类字段来添加方法,代码可能看起来更易读,但类字段会被添加到实例本身,而不是原型中。如果我们创建 100 个实例,就会创建 100 个方法副本!
如果您有任何问题、意见或反馈,请告诉我。关注我,每周都会发布关于 JavaScript、React、Python 和 Django 的最新文章!
文章来源:https://dev.to/guin/learn-public-class-field-syntax-by-refactoring-a-react-component-njh