同vue一样,react也是有生命周期的。我们通过下面这个demo来学习react 的生命周期如何在类组件中实现。
react声明周期钩子简介
生命周期函数是React组件中的一些方法,它们在组件的不同状态下被调用,可以在这些函数中实现一些特定的行为。React组件的生命周期可以分为三个阶段:
- 挂载阶段(Mounting):组件被创建并插入到DOM中
- 更新阶段(Updating):组件被重新渲染
- 卸载阶段(Unmounting):组件被从DOM中移除
下面是React中常用的生命周期函数:
- constructor(props):初始化组件的状态和属性。
- getDerivedStateFromProps(props, state):在组件更新前被调用。返回值将会被添加到组件的状态中。
- render():渲染组件。必须返回一个React元素或null。
- componentDidMount():组件已经被挂载到DOM中。可以在这个函数中发送请求。
- shouldComponentUpdate(nextProps, nextState):组件将要更新。可以在这个函数中判断是否需要更新组件。
- getSnapshotBeforeUpdate(prevProps, prevState):在组件更新前被调用。返回值会传递给componentDidUpdate()函数。
- componentDidUpdate(prevProps, prevState, snapshot):组件已经更新完毕。可以在这个函数中更新状态或者发送请求。
- componentWillUnmount():组件将要被卸载,可以在这个函数中清除定时器或者取消请求。
react的生命周期写法
如图,页面加载时,页面文字透明度逐渐降低,当透明度小于零时,透明度变为1;当点击按钮时,页面卸载。
分析这个页面,我们知道当页面加载时,需要触发文字渐变相关函数;点击按钮实现页面注销。unmountComponentAtNode
我们先实现页面销毁
上述代码中,我们通过ReactDOM.unmountComponentAtNode方法实现了类组件的销毁。unmountComponentAtNode顾名思义,销毁组件在某个节点,因此,其入参就是当前节点id// 1、创建类组件 class Life extends React.Component { tangPing = () => { ReactDOM.unmountComponentAtNode(document.getElementById("test")); }; render() { return ( <div> <h1 style={ { opacity: this.state.opacity }}>好好学习,天天向上</h1> <button onClick={ this.tangPing}>学个锤子</button> </div> ); } } // 渲染组件 ReactDOM.render(<Life />, document.getElementById("test"));
componentDidMount
componentDidMount是组件挂载到DOM中的钩子,类似于vue中的mount钩子。我们在这个钩子中添加一些逻辑。
componentDidMount同render函数一样,是类原型上的方法,所以采用componentDidMount() {}的写法而不采用componentDidMount = () =>{}的写法。class Life extends React.Component { state = { opacity: 1, }; tangPing = () => { ReactDOM.unmountComponentAtNode(document.getElementById("test")); }; // 组件已经被挂载到DOM中 componentDidMount() { setInterval(() => { // 获取原状态 let { opacity } = this.state; // 减少0.1 opacity -= 0.1; // 设置新的透明度 if (opacity <= 0) opacity = 1; this.setState({ opacity }); }, 200); } render() { return ( <div> <h1 style={ { opacity: this.state.opacity }}>好好学习,天天向上</h1> <button onClick={ this.tangPing}>学个锤子</button> </div> ); } }
页面效果:
可以看出,页面效果实现了,但是,当我们销毁组件时,控制台有报错。
报错原因可以看出来,组件销毁了,setInterval执行时,找不到state状态值了。要解决这个问题,最简单的,就是销毁组件时,清空定时器:tangPing = () => { clearInterval(this.timer); ReactDOM.unmountComponentAtNode(document.getElementById("test")); }; // 组件已经被挂载到DOM中 componentDidMount() { this.timer = setInterval(() => { // 获取原状态 let { opacity } = this.state; // 减少0.1 opacity -= 0.1; // 设置新的透明度 if (opacity <= 0) opacity = 1; this.setState({ opacity }); }, 200); }
componentWillUnmount
除了用上面的方法清空定时器,我们也可以在页面注销钩子里清空定时器。
componentWillUnmount是组件将要被卸载时的钩子。类似于vue的beforeDestory钩子,可以在这个函数中清除定时器或者取消请求。class Life extends React.Component { state = { opacity: 1, }; tangPing = () => { ReactDOM.unmountComponentAtNode(document.getElementById("test")); }; componentWillUnmount() { clearInterval(this.timer); } // 组件已经被挂载到DOM中 componentDidMount() { this.timer = setInterval(() => { // 获取原状态 let { opacity } = this.state; // 减少0.1 opacity -= 0.1; // 设置新的透明度 if (opacity <= 0) opacity = 1; this.setState({ opacity }); }, 200); } render() { return ( <div> <h1 style={ { opacity: this.state.opacity }}>好好学习,天天向上</h1> <button onClick={ this.tangPing}>学个锤子</button> </div> ); } }