React 生命周期及使用场景详解

阅读时长 8 分钟读完

在 React 中,组件的生命周期是非常重要的概念之一。React 生命周期指的是组件在它被创建和销毁的过程中所经历的状态和方法调用的顺序。本篇文章将详细讲解 React 生命周期和常见的使用场景,为初学者提供深度学习和指导意义。

一、React 生命周期

React 生命周期可以分为三个阶段:组件创建阶段、组件存在阶段和组件销毁阶段。每个阶段包含了一些组件特定的钩子函数,可以在不同的时间点执行特定的操作。

1.1 组件创建阶段

在组件创建阶段,React 会调用一些特定的函数来准备组件实例,这些函数被称为钩子函数。

1.1.1 constructor()

在组件创建时,首先会调用 constructor() 函数。constructor() 函数是 JavaScript 类的构造函数,用于初始化组件的状态、绑定成员函数和创建 Refs。

constructor(props) { super(props); this.state = { count: 0 }; this.handleClick = this.handleClick.bind(this); this.myRef = React.createRef(); }

1.1.2 static getDerivedStateFromProps()

接下来会调用 static getDerivedStateFromProps() 函数。该函数是在组件创建或者组件更新后,React 会传入新的属性 props 和之前的状态 state,并计算出新的状态返回。该函数适用于稳定的计算过程,一般不建议使用。

static getDerivedStateFromProps(props, state) { return { count: props.count }; }

1.1.3 render()

接下来会调用 render() 函数,返回一个 React 元素或 null,用于描述组件的UI呈现。该函数应该是纯函数,不应该有副作用,即不能修改组件状态和DOM。

render() { return

{this.state.count}
; }

1.1.4 componentDidMount()

在组件渲染完成后,会调用 componentDidMount() 函数,该函数用于初始化第三方库、加载数据等操作。该函数执行后,组件已经被挂载到DOM树上,可以访问和修改组件的DOM和状态。

componentDidMount() { this.myRef.current.addEventListener('click', this.handleClick); }

1.2 组件存在阶段

在组件存在阶段,组件已经被渲染到了页面上,并且会根据props和state的变化而重新渲染。

1.2.1 static getDerivedStateFromProps()

在组件更新之前,React 会调用 static getDerivedStateFromProps() 函数,对于需要在组件更新时改变 state 的场景可以使用该函数。该函数返回一个对象来更新组件的状态,或者返回 null 值来表示组件不需要更新。

static getDerivedStateFromProps(props, state) { if (props.count !== state.count) { return { count: props.count }; } return null; }

1.2.2 shouldComponentUpdate()

接下来,React 会调用 shouldComponentUpdate() 函数,该函数是一个优化性能的钩子函数。默认情况下,React 认为组件需要重新渲染,但是在某些情况下,我们不希望组件重新渲染。shouldComponentUpdate() 函数返回一个布尔值,true 表示需要重新渲染,false表示不需要。在这个函数中,我们可以根据当前属性和状态以及下一个属性和状态,来决定是否需要重新渲染组件。

shouldComponentUpdate(nextProps, nextState) { if (this.props.count === nextProps.count && this.state.count === nextState.count) { return false; } return true; }

1.2.3 render()

接着调用 render() 函数重新生成组件的 UI 呈现。在这个过程中,React 会对比前后生成的 UI,并根据变化的部分进行更新操作。

1.2.4 getSnapshotBeforeUpdate()

在 render() 函数调用后,React 会调用 getSnapshotBeforeUpdate() 函数,该函数返回一个快照,用于让我们在组件更新后恢复之前的某些数据。该函数通常与 componentDidUpdate() 函数一起使用。

getSnapshotBeforeUpdate(prevProps, prevState) { if (prevState.count < this.state.count) { return { scrollTop: this.myRef.current.scrollTop }; } return null; }

1.2.5 componentDidUpdate()

在组件更新完成后,会调用 componentDidUpdate() 函数。该函数中可以进行与 componentDidMount() 类似的操作,用于更新第三方库、加载数据等操作。但是需要注意的是,该函数中不能通过 setState() 函数直接修改组件的状态,这样会导致组件不断更新导致死循环。

componentDidUpdate(prevProps, prevState, snapshot) { if (snapshot !== null) { this.myRef.current.scrollTop = snapshot.scrollTop; } }

1.3 组件销毁阶段

在组件销毁阶段,会调用一个钩子函数 componentWillUnmount(),该函数用于清理一些组件的引用、事件监听取消等操作。

componentWillUnmount() { this.myRef.current.removeEventListener('click', this.handleClick); }

二、React 生命周期使用场景

接下来我们将介绍一些常见的生命周期使用场景。

2.1 构造组件状态

使用 constructor() 函数构造组件状态,该函数只会在组件创建时调用一次。constructor() 函数中应该使用 setState() 函数初始化组件状态。setState() 函数调用后,React 会重新渲染组件,并更新组件状态。

2.2 加载数据

使用 componentDidMount() 函数在组件挂载后加载数据。该函数中可以调用数据接口获取数据,并修改组件状态。状态修改后,React 会重新渲染组件。

componentDidMount() { fetch('https://api.example.com/data') .then(response => response.json()) .then(data => { this.setState({ data }); }); }

2.3 更新组件状态

当组件需要在 props 或其他状态发生变化后重新渲染时,使用 shouldComponentUpdate() 函数和 componentDidUpdate() 函数来进行更新。

在 shouldComponentUpdate() 函数中比较新旧状态和属性的值,可以决定是否需要重新渲染组件。在 componentDidUpdate() 函数中可以更新组件状态并进行其他操作。

shouldComponentUpdate(nextProps, nextState) { if (this.props.count === nextProps.count && this.state.count === nextState.count) { return false; } return true; }

componentDidUpdate(prevProps, prevState, snapshot) { if (snapshot !== null) { this.myRef.current.scrollTop = snapshot.scrollTop; } }

2.4 卸载事件处理函数

当需要卸载事件处理函数时,在 componentWillUnmount() 函数中取消事件监听,清空定时器或者其他清理操作。

componentWillUnmount() { this.myRef.current.removeEventListener('click', this.handleClick); }

三、总结

本篇文章详细讲解了 React 生命周期和常见的使用场景。对于初学者来说,掌握 React 生命周期和使用场景非常重要。通过合理地使用 React 生命周期和场景,可以更好地构造和管理 React 组件。同时,也需要注意在生命周期函数中避免产生副作用,保证函数的纯粹性。希望本篇文章对大家有所帮助,更加深入地了解 React 生命周期。

代码示例:https://codesandbox.io/s/react-lifecycle-demo-wt4im

来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/64f64226f6b2d6eab3ed7359

纠错
反馈