React Native 组件的生命周期与 React 的类组件生命周期一致(因为 React Native 基于 React)。不过随着 React Hooks 的普及,函数组件和 Hooks 已成为更主流的开发方式。以下是类组件和函数组件的生命周期管理:
一、类组件的生命周期
1. 挂载阶段(Mounting)
constructor(props)
初始化组件的state和绑定方法。注意: 必须调用super(props)。static getDerivedStateFromProps(props, state)
在组件创建或接收到新props时调用,返回一个对象来更新state,或返回null表示不更新。render()
必须实现的方法,返回 JSX 或null。此时不能执行副作用(如网络请求)。componentDidMount()
组件挂载后调用,适合执行副作用(如网络请求、订阅事件、操作 DOM)。
2. 更新阶段(Updating)
触发条件:props 变化、state 变化、父组件重新渲染。
static getDerivedStateFromProps(props, state)
同挂载阶段,用于根据新的props更新state。shouldComponentUpdate(nextProps, nextState)
返回true(默认)允许重新渲染,返回false阻止渲染。用于性能优化。render()
重新渲染组件。getSnapshotBeforeUpdate(prevProps, prevState)
在 DOM 更新前调用,返回值会作为参数传递给componentDidUpdate。常用于保存滚动位置等。componentDidUpdate(prevProps, prevState, snapshot)
组件更新后调用,适合执行副作用(如根据新数据更新 DOM)。
3. 卸载阶段(Unmounting)
componentWillUnmount()
组件销毁前调用,用于清理资源(如取消网络请求、移除订阅、清除定时器)。
4. 已废弃的生命周期方法(避免使用)
componentWillMount()→ 改用constructor或componentDidMount。componentWillReceiveProps()→ 改用getDerivedStateFromProps。componentWillUpdate()→ 改用getSnapshotBeforeUpdate。
二、函数组件的生命周期(使用 Hooks)
函数组件通过 Hooks 模拟生命周期逻辑:
1. 挂载阶段
useEffect(() => { ... }, [])
依赖项数组为空时,等同于componentDidMount,用于初始化操作。
2. 更新阶段
useEffect(() => { ... }, [dependency])
依赖项变化时触发,等同于componentDidUpdate。例如:useEffect(() => { fetchData() }, [userId])。
3. 卸载阶段
useEffect(() => { return () => { ... } }, [])
返回的清理函数等同于componentWillUnmount。例如:清除定时器或取消订阅。
其他常用 Hooks
useState:管理组件状态。useMemo和useCallback:优化性能,避免不必要的计算或渲染。
三、生命周期使用场景
- 数据请求:在
componentDidMount或useEffect中发起网络请求。 - 订阅事件:在
componentDidMount中订阅,在componentWillUnmount中取消。 - 手动操作 DOM:在
componentDidMount或componentDidUpdate中操作。 - 性能优化:通过
shouldComponentUpdate或React.memo避免无效渲染。
四、示例对比
类组件
class Example extends React.Component {
componentDidMount() {
console.log("组件已挂载");
}
componentDidUpdate() {
console.log("组件已更新");
}
componentWillUnmount() {
console.log("组件即将卸载");
}
render() {
return <Text>Hello</Text>;
}
}
函数组件
function Example() {
useEffect(() => {
console.log("组件已挂载或更新");
return () => {
console.log("组件即将卸载");
};
}, []); // 空依赖表示仅在挂载和卸载时执行
return <Text>Hello</Text>;
}
五、最佳实践
- 优先使用函数组件和 Hooks:代码更简洁,逻辑复用更灵活。
- 避免滥用生命周期:如
getDerivedStateFromProps可能导致复杂逻辑,可考虑状态管理库(如 Redux)。 - 注意内存泄漏:在
componentWillUnmount或useEffect清理函数中释放资源。
掌握生命周期有助于编写高效、可维护的 React Native 应用。