Reactv16.8.6生命周期函数

摘要:
PureComponent对props和state进行了简单的比较,并减少了跳过必要更新的可能性。此生命周期的返回值将作为参数传递给componentDidUpdate()类ScrollingListextendsReact。组件{constructor{super;this.listRef=React.createRef();}GetSnapshotBeforeUpdate{//我们是否向列表中添加新项?==null){constlist=this.listRef.current;list.sollTop=list.sollHeight snapshot;}}render(){return;}}在上面的示例中,重点是从getSnapshotBeforeUpdate读取scrollHeight属性,因为“渲染”阶段生命周期和“提交”阶段生命生命周期之间可能存在延迟。ComponentDidUpdate此方法将在数据更新后立即调用,不会调用第一次加载。如果在该方法中使用setState,则必须将其放置在条件语句中,否则将导致无休止的循环。它还会导致额外的重新渲染,这会影响componentDidUpdate的性能{//典型用法:if(this.props.userID!

组件生命周期函数

React 主动调用的方法,也可重写这些方法

生命周期图谱

当组件实例被创建并插入 DOM 中时,其生命周期调用顺序如下:

constructor(props)

如果不需要初始化 state 或 不进行方法绑定,则不需要使用该方法

在组件挂载之前会先调用该方法,在实现构造函数时必须先调用super(props)方法,否则会出现BUG
通常,构造函数仅用于两种情况:1. 初始化 state 2. 为事件处理函数绑定实例
在该方法中不要使用 setState() 方法,在其他方法中使用setState()改变 state
为什么 props 复制给 state 会产生 bug

constructor(props) {
  super(props);
  // 不要在这里调用 this.setState()
  this.state = {
    counter: 0,
    name:props.name // 严禁这样赋值,props.name值更新时 state.name并不会更新
   };
  this.handleClick = this.handleClick.bind(this);
}

static getDerivedStateFromProps() (此方法不常用)

此方法会在 render 方法之前调用,并且初始化和数据更新时都会调用,它返回一个对象更新 state,如果返回null 则不更新任何内容。

此方法适用于 state 值在任何时候都取决于props 的情况。

render()

render 是 class 组件必须实现的方法

当该方法被调用时,它会监测 props 和 state 的变化,并且返回以下类型之一:

  • React 元素:通过JSX创建,渲染成对应的DOM节点或自定义组件
  • 数组或fragments: 使render方法可以返回多个元素 frgments
  • Portals:可以渲染子节点到不同的DOM子树汇中portals
  • 字符串或数值类型: 在DOM中会被渲染为文本节点、
  • Boolean 或 null:什么都不渲染

render方法最好为纯函数,即在不修改组件 state情况下,每次调用时都返回相同的结果,并且不会直接与浏览器交互

如果要和浏览器交互,可以在其他生命周期函数中执行,注意:shoouldComponentUpdate方法中返回false,将不会调用render方法

class Example extemds React.Component{
shouldComponentUpdate(nextProps, nextState){
  return false
}
render(){ // 不会执行
  <div>owen</div>
  }
}

componentDIdMount()

此方法会在组件挂载后(插入DOM树中)调用,初始化的数据的好地方

组件的 propsstate 发生变化会触发更新。组件更新的生命周期调用顺序如下:

static getDerivedStateFromProps() (此方法不常用)(已解释)

shouldComponentUpdate(nextProps, nextState) (此方法不常用)

当state 或 props 变化时该方法会在渲染执行前调用默认返回值为true,首次加载不会被调用

根据该方法的返回值判断组件输出是否受当前 state 或 props 更改的影响。默认为 state 每次更新重新渲染

此方法进仅做为性能优化的方式存在,不要企图依靠此方法来“阻止”渲染,因为这可能会产生 bug。你应该考虑使用内置的 PureComponent 组件,而不是手动编写 shouldComponentUpdate()。PureComponent 会对 props 和 state 进行浅层比较,并减少了跳过必要更新的可能性。

render()(已解释)

getSnapshotBeforeUpdate() (此方法不常用)

此方法在最近一次渲染输出(提交到DOM节点)之前调用。使组件能在发送更改前从DOM中捕获一些信息(如 位置)。此生命周期的返回值将作为参数传递给 componentDidUpdate()

class ScrollingList extends React.Component {
  constructor(props) {
    super(props);
    this.listRef = React.createRef();
  }

  getSnapshotBeforeUpdate(prevProps, prevState) {
    // 我们是否在 list 中添加新的 items ?
    // 捕获滚动​​位置以便我们稍后调整滚动位置。
    if (prevProps.list.length < this.props.list.length) {
      const list = this.listRef.current;
      return list.scrollHeight - list.scrollTop;
    }
    return null;
  }

  componentDidUpdate(prevProps, prevState, snapshot) {
    // 如果我们 snapshot 有值,说明我们刚刚添加了新的 items,
    // 调整滚动位置使得这些新 items 不会将旧的 items 推出视图。
    //(这里的 snapshot 是 getSnapshotBeforeUpdate 的返回值)
    if (snapshot !== null) {
      const list = this.listRef.current;
      list.scrollTop = list.scrollHeight - snapshot;
    }
  }

  render() {
    return (
      <div ref={this.listRef}>{/* ...contents... */}</div>
    );
  }
}

上述示例中,重点是从 getSnapshotBeforeUpdate 读取 scrollHeight 属性,因为 “render” 阶段生命周期(如 render)和 “commit” 阶段生命周期(如 getSnapshotBeforeUpdate 和 componentDidUpdate)之间可能存在延迟。

componentDidUpdate(prevProps, prevState, snapshot)

此方法会在数据更新后立即调用,首次加载不会被调用,在此方法中使用 setState必须将它放到条件语句中,否则会导致死循环。还会导致额外的重新渲染,影响性能

componentDidUpdate(prevProps) {
  // 典型用法(不要忘记比较 props):
  if (this.props.userID !== prevProps.userID) {
    this.fetchData(this.props.userID);
  }
}

注意:如果 shouldComponentUpdate() 返回值为 false,则不会调用 componentDidUpdate()。

当组件从 DOM 中移除时会调用如下方法:

componentWillUnmount()

此方法会在组件卸载销毁前调用,可以执行必要的清理操作,如 定时器,取消网络请求,或清除componentDidMount() 中创建的订阅等。

当渲染过程,生命周期,或子组件的构造函数中抛出错误时,会调用如下方法:

Error boundaries:捕获渲染期间及整个树的函数发送的错误,渲染降级 UI,但自身的错误无法捕获 React 16中的错误处理

static getDerivedStateFromError(error) (此方法不常用)

次生命周期会在后代组件抛出错误后调用,将错误作为参数,返回一个值更新state,在渲染期间不允许出现副作用,建议使用 componentDidCatch()

componentDidCatch(error, info) (此方法不常用)

此方法在后代组件抛出错误后被调用

如果发生错误,可以通过调用 setState 使用 componentDidCatch() 渲染降级 UI,但在未来的版本中将不推荐这样做。 可以使用静态 getDerivedStateFromError() 来处理降级渲染。

class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

  static getDerivedStateFromError(error) {
    // 更新 state 使下一次渲染可以显降级 UI
    return { hasError: true };
  }
  componentDidCatch(error, info) {
    // "组件堆栈" 例子:
    //   in ComponentThatThrows (created by App)
    //   in ErrorBoundary (created by App)
    //   in div (created by App)
    //   in App
    logComponentStackToMyService(info.componentStack);
  }
  render() {
    if (this.state.hasError) {
      // 你可以渲染任何自定义的降级  UI
      return <h1>Something went wrong.</h1>;
    }

    return this.props.children;
  }
}

Example

class Square extends React.Component {

  constructor(props) {
    super(props);
    this.state = {
      value:null
    };
  }
  static getDerivedStateFromProps(props, state) {
    // 实例化组件之后以及在重新呈现组件之前调用新的静态生命周期。它可以返回要更新的对象state,或null指示新对象props不需要任何state更新。
  }
   componentDidMount() { // 组件被渲染到 DOM 中后运行
    console.log('DidMount: 1')
  }

  shouldComponentUpdate(){
    // 更新前
  }

  getSnapshotBeforeUpdate(){
    //
  }
  componentDidUpdate() {
    // 更新后
  }

  static getDerivedStateFromError() {
      // 出错时
  }
  componentDidCatch(){
    // capture error
  }
  compoentwillUnmount(){ // 组件被删除的时候
    console.log('UnMount: end')

  }
  render() {
    return (
      <button className="square" onClick = {()=>{this.setState({value:'X'})}
      }>
        {this.state.value}
      </button>
    );
  }
}

Owen 的个人博客

参考资料:React官网

免责声明:文章转载自《Reactv16.8.6生命周期函数》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇C#读取EXCEL文件的三种经典方法Qt 单元测试下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

C#跨线程修改控件——从MSIL和汇编看Invoke, 多线程, 事件与事件委托

相信大家刚开始写winform的时候都遇到过这样的问题,当跨线程修改控件属性时会遇到如下的异常: 线程间操作无效: 从不是创建控件"progressBar1"的线程访问它。 这是相应的产生上述异常的代码: 1 #region Auto-Generated Properties 2 3 // DelegateDemo - Director.cs...

Openstack_通用技术_RPC 远程异步调用

目录 目录 RPC 一个通过 HTTP Request 调用操作函数的 RPC 实现样例 环境 接收 HTTP Request RPC 调用具体的操作函数 测试 RPC RPC: 同一个项目内的不同服务进程之间的交互方式。为不同的进程服务提供了 call()(同步) 和 cast()(异步) 两种调用方式。 问题 1: 在一个 Opensta...

箭头函数及this指向问题

  全局环境下 在全局环境下,this 始终指向全局对象(window), 无论是否严格模式; console.log(this.document === document); // true // 在浏览器中,全局对象为 window 对象: console.log(this === window); // true this.a = 37; co...

Hadoop实战之二~ hadoop作业调度详解(1)

对Hadoop的最感兴趣的地方,也就在于Hadoop的作业调度了,在正式介绍如何搭建Hadoop之前,深入理解一下Hadoop的作业调度很有必要。我们不一定能用得上Hadoop,但是如果理通顺Hadoop的分布式调度原理,在有需要的时候未必不能自己写一个Mini Hadoop~: ) 开始 本文转载自:http://www.cnblogs.com/ship...

react dva发送请求详解(转)

1,在jsx页面派发任务,可以在componentWillMount的生命周期内,使用this.props.dispatch方法派发,需要先引用connect模块,不引用会报错 import { connect } from 'dva'; 在类中操作: class 类名 extends React.Component { constructor(pro...

Unity中Invoke函数基础用法

public voidInvoke(stringmethodName, floattime); methodName是方法名,time 是具体几秒 在具体事件以后调用这个方法 也就是说,Invoke("SendMessage",5) ,表示的是在“5s”以后执行“SendMessage”方法。 使用Invoke方法需要注意以下三点: 1、它应该在Start...