Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

【React】React 生命周期 #35

Open
Tracked by #6
swiftwind0405 opened this issue Apr 2, 2020 · 0 comments
Open
Tracked by #6

【React】React 生命周期 #35

swiftwind0405 opened this issue Apr 2, 2020 · 0 comments
Labels

Comments

@swiftwind0405
Copy link
Owner

swiftwind0405 commented Apr 2, 2020

为了更好的支持异步渲染(Async Rendering),解决一些生命周期滥用可能导致的问题,React 从 V16.3 开始,对生命周期进行渐进式调整,同时在官方文档也提供了使用的最佳实践。
可利用这个网站 React Lifecycle Methods diagram,查看各版本的生命周期图。

React 的生命周期大致分为:

  • 组件装载(Mount)组件第一次渲染到 Dom 树
  • 组件更新(update)组件 state,props 变化引发的重新渲染
  • 组件卸载(Unmount)组件从 Dom 树删除

从 React v16 开始,还对生命周期加入了错误处理(Error Handling)。

V16.3.0之前

创建阶段(Mounting)

  1. constructor(props, context)
  2. componentWillMount()
  3. render()
  4. componentDidMount()

更新阶段(Updating)

props发生变化时

  1. componentWillReceiveProps(nextProps, nextContext)
  2. shouldComponentUpdate(nextProps, nextState, nextContext)
  3. componentWillUpdate(nextProps, nextState, nextContext)
  4. render
  5. componentDidUpdate(prevProps, prevState, snapshot)

state发生变化时

  1. shouldComponentUpdate(nextProps, nextState, nextContext)
  2. componentWillUpdate(nextProps, nextState, nextContext)
  3. render
  4. componentDidUpdate(prevProps, prevState, snapshot)

卸载阶段(Unmounting)

  1. componentWillUnmount()

图示:
image

V16.3.0之后

创建阶段(Mounting)

  1. constructor(props, context)
  2. static getDerivedStateFromProps(props, status)
  3. render()
  4. componentDidMount()

更新阶段(Updating)

props / state 发生变化时

  1. static getDerivedStateFromProps(props, status)
  2. shouldComponentUpdate(nextProps, nextState, nextContext)
  3. render
  4. getSnapshotBeforeUpdate(prevProps, prevState)
  5. componentDidUpdate(prevProps, prevState, snapshot)

卸载阶段(Unmounting)

  1. componentWillUnmount()

图示:
image

删除生命周期

  1. componentWillMount
  2. componentWillReceiveProps
  3. componentWillUpdate

所有被删除的生命周期函数,目前还凑合着用,但是只要用了,开发模式下会有红色警告,在下一个大版本(也就是React v17)更新时会彻底废弃。会保留另外一种形式:

  1. UNSAFE_componentWillMount()
  2. UNSAFE_componentWillReceiveProps
  3. UNSAFE_componentWillUpdate

注意: getDerivedStateFromProps/getSnapshotBeforeUpdate 和 componentWillMount/componentWillReceiveProps/componentWillUpdate 如果同时存在,React会在控制台给出警告信息,且仅执行 getDerivedStateFromProps/getSnapshotBeforeUpdate 【[email protected]

React-Hooks 的生命周期

image

生命周期详解

constructor()

constructor(props)

构造函数通常用于:

  • 使用 this.state 来初始化 state
  • 给事件处理函数绑定 this

注意:ES6 子类的构造函数必须执行一次 super()。React 如果构造函数中要使用 this.props,必须先执行 super(props)。

static getDerivedStateFromProps()

static getDerivedStateFromProps()

当创建时、接收新的 props 时、setState 时、forceUpdate 时会执行这个方法。

这是一个静态方法,参数 nextProps 是新接收的 propsprevState 是当前的 state。返回值(对象)将用于更新 state,如果不需要更新则需要返回 null

下面是官方文档给出的例子

class ExampleComponent extends React.Component {
  // Initialize state in constructor,
  // Or with a property initializer.
  state = {
    isScrollingDown: false,
    lastRow: null,
  };

  static getDerivedStateFromProps(props, state) {
    if (props.currentRow !== state.lastRow) {
      return {
        isScrollingDown: props.currentRow > state.lastRow,
        lastRow: props.currentRow,
      };
    }

    // Return null to indicate no change to state.
    return null;
  }
}

这个方法的常用作用也很明显了:父组件传入新的 props 时,用来和当前的 state 对比,判断是否需要更新 state。以前一般使用 componentWillReceiveProps 做这个操作。

这个方法在建议尽量少用,只在必要的场景中使用,一般使用场景如下:

  1. 无条件的根据 props 更新 state
  2. propsstate 的不匹配情况更新 state

详情可以参考官方文档的最佳实践 You Probably Don’t Need Derived State

render

render()

每个类组件中,render() 是唯一必须的方法。

render() 正如其名,作为渲染用,可以返回下面几种类型:

  • React 元素(React elements)
  • 数组(Arrays)
  • 片段(fragments)
  • 插槽(Portals)
  • 字符串或数字(String and numbers)
  • 布尔值或 null(Booleans or null)

里面不应该包含副作用,应该作为纯函数。不能使用 setState。

componentDidMount()

componentDidMount()

组件完成装载(已经插入 DOM 树)时,触发该方法。这个阶段已经获取到真实的 DOM。

一般用于下面的场景:

  • 异步请求 ajax
  • 添加事件绑定(注意在 componentWillUnmount 中取消,以免造成内存泄漏)

可以使用 setState,触发re-render,影响性能。

componentWillUnmount()

componentWillUnmount()

在组件卸载或者销毁前调用。这个方法主要用来做一些清理工作,例如:

  • 取消定时器
  • 取消事件绑定
  • 取消网络请求

注意:不能使用 setState

componentDidCatch()

componentDidCatch(err, info)

任何子组件在渲染期间,生命周期方法中或者构造函数 constructor 发生错误时调用。

错误边界不会捕获下面的错误:

  • 事件处理 (Event handlers) (因为事件处理不发生在 React 渲染时,报错不影响渲染)
  • 异步代码 (Asynchronous code) (e.g. setTimeout or requestAnimationFrame callbacks)
  • 服务端渲染 (Server side rendering)
  • 错误边界本身(而不是子组件)抛出的错误

参考资料

@swiftwind0405 swiftwind0405 changed the title 【Day35】React 生命周期 【React】React 生命周期 Apr 29, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant