React:类组件 VS 带 Hooks 的函数组件
类组件
在 React Hooks 之前,当我们想要创建一个动态组件时,我们必须创建一个类组件并使用生命周期方法来改变状态,以使其可重用和封装。
通过创建 ES6 类,该类需要在其中扩展React.Component
一个render
方法,该方法将返回 JSX 标记。此外,我们需要在构造函数中使用 分配初始状态this.state
。例如,这里我们使用类创建一个简单的时钟组件。为了使时钟工作,我们必须向我们的类添加生命周期方法。我们将元素放入 DOM,这在 React 中称为mounting
。同样,我们从 DOM 中删除元素,这称为unmounting
。在 React 中,挂载组件将调用以下四种内置方法:
- 构造函数()
- 获取派生状态(来自Props)
- 使成为()
- 组件挂载()
更多信息请阅读React Doc:常用的生命周期方法
在我们的示例中,我们在构造函数中设置了初始状态,并定义componentDidMount()
为每秒设置一次时间。因此,时钟将每秒使用当前时间更新状态。
class ClockUsingClass extends React.Component {
constructor(props) {
super(props)
this.state = { date: new Date() }
}
componentDidMount() {
this.time = setInterval(() => {
this.changeTime()
}, 1000)
}
componentWillUnmount() {
clearInterval(this.time)
}
changeTime() {
this.setState({ date: new Date() })
}
render() {
return (
<div className="clock">
<h1>Hello! This is a class component clock.</h1>
<h2>It is {this.state.date.toLocaleTimeString()}.</h2>
</div>
)
}
}
显然我们可以看到,对于基于类的组件,我们需要几个步骤才能使其能够进行状态改变:
- 创建一个具有
constructor(props)
和render()
方法的类。 this.state
使用构造函数中的语句设置初始状态。- 用于
this.setState()
更新状态。 - 使用诸如 、 等生命周期方法
componentDidMount()
来componentWillUnmount()
改变componentDidUpdate()
状态
带钩子的函数组件
Hooks 是 React 16.8 中的新增功能。Hooks 最实用的功能是它允许在不使用 class 的情况下使用 state。
最常用的钩子有两种:状态钩子 ——useState
和效果钩子 —— useEffect
。
状态钩子允许你在函数组件中添加状态。this.state
我们不需要使用构造函数中的语句设置初始状态,而是可以{ useState }
从 React 导入,这样你就可以将初始状态设置为参数。状态钩子将返回一对值:当前状态和更新它的函数。通常,我们会useState
像这样使用:
const [time, setTime] = useState(new Date())
效果钩子将在第一次 DOM 更新时调用。我们可以传入一个函数useEffect
,每次 DOM 更新时,函数useEffect
也会被调用。此外,效果钩子允许你传入一个数组作为第二个参数,该数组包含将触发效果钩子的所有依赖项。如果任何依赖项发生变化,效果钩子将再次运行。此功能为我们提供了一种更有效的 Ajax 请求方式。你不必每次更新 DOM 时都发出请求,而是可以传入仅在这些值发生变化时发出请求的依赖项。useEffect
可以像这样使用:
useEffect(() => {
setInterval(() => {
changeTime()
}, 1000)
})
因此,我们在这里用钩子重写上面创建的时钟
const ClockUsingHooks = props => {
const [time, setTime] = useState(new Date())
const changeTime = () => {
setTime(new Date())
}
useEffect(() => {
const tick = setInterval(() => {
changeTime()
}, 1000)
return () => clearInterval(tick)
})
return (
<div className="clock">
<h1>Hello! This is a function component clock.</h1>
<h2>It is {time.toLocaleTimeString()}.</h2>
</div>
)
}
概括
对比这两种创建组件的方式,我们可以清楚地看到,钩子需要的代码更少,而且更易于阅读和理解。钩子为我们提供了一种更高效的方法来替换生命周期方法。
查看 repo 来制作一个简单的时钟
鏂囩珷鏉ユ簮锛�https://dev.to/danielleye/react-class-component-vs-function-component-with-hooks-13dg