React Native 生命周期终极指南:类组件 vs Hooks 函数组件

249 阅读3分钟

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 应用。