当前位置:   article > 正文

react中在componentDidMount生命周期函数中调用了多个this.setState报错_在componentdidmount中setstate

在componentdidmount中setstate

在这里插入图片描述
报错:超过最大更新深度。当组件在componentWillUpdate或componentDidUpdate中重复调用setState时,就会发生这种情况。React限制嵌套更新的数量,以防止无限循环。
在componetDidMount和componentDidUpdate中:

componentDidMount(): void {
    const winW = document.documentElement.clientWidth || document.body.clientWidth;
    const winH = document.documentElement.clientHeight || document.body.clientHeight;
    const width = winW/2;
    const height = winH/4;
    const cx = winW/8;
    const cy = winH/10;
    this.setState({width,height,cx,cy})

    if(this.props.pieName === 'dayElectric'){
       var responece:object = FloorData.dayElectric.map((item:Electric,index:number)=>item)
    }
    if(this.props.pieName === 'monthElectric'){
      var responece:object = FloorData.monthElectric.map((item:Electric,index:number)=>item)
    }
    if(this.props.pieName === 'yearElectric'){
      var responece:object = FloorData.yearElectric.map((item:Electric,index:number)=>item)
  
    }

  }

  componentDidUpdate(prevProps: Readonly<RouteComponentProps>, prevState: Readonly<{}>, snapshot?: any): void {
    const winW = document.documentElement.clientWidth || document.body.clientWidth;
    const winH = document.documentElement.clientHeight || document.body.clientHeight;
    const width = winW/2;
    const height = winH/4;
    const cx = winW/14;
    const cy = winH/14;
    this.setState({width,height,cx,cy})
  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

修改后:

 // 会在调用 render 方法之前调用,并且在初始挂载及后续更新时都会被调用
  static getDerivedStateFromProps(nextProps:RouteComponentProps<{type:string}>, prevState:any) {
    var responeceDate:any[] =[];
    const winW = document.documentElement.clientWidth || document.body.clientWidth;
    const winH = document.documentElement.clientHeight || document.body.clientHeight;
    const width = winW/2;
    const height = winH/4;
    const {type} = nextProps;
    if(type === '0'){
      responeceDate = FloorData.dayElectric
    }else if(type === '1'){
      responeceDate = FloorData.monthElectric
    }else if(type === '2'){
      responeceDate = FloorData.yearElectric
    }
      return {//返回一个对象来更新 state,如果返回 null则不更新任何内容。
        data:responeceDate,
        width,height
      };
    // return null;
  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

componentDidMount()
会在组件挂载后(插入DOM树中) 立即调用。如需通过网络请求获取数据,此处是实例化请求的好地方
你可以在 componentDidMount() 里直接调用 setState()。它将触发额外渲染,但此渲染会发生在浏览器更新屏幕之前。如此保证了即使在 render() 两次调用的情况下,用户也不会看到中间状态。请谨慎使用该模式,因为它会导致性能问题。

componentDidUpdate()
会在更新后会被立即调用。首次渲染不会执行此方法。
你也可以在 componentDidUpdate() 中直接调用 setState(),但请注意它必须被包裹在一个条件语句里,正如上述的例子那样进行处理,否则会导致死循环。它还会导致额外的重新渲染,虽然用户不可见,但会影响组件性能。

conponentWillUnmount()
会在组件卸载及销毁之前调用。在此方法中执行必要的清理操作,例如清除timer,取消网络请求或清除在componentDidMount() 中创建的订阅等。
componentWillUnMount() 中不应该调用setState(),因为该组件将永远不会重新渲染,组件实例卸载后将永远不会再挂载它。

static getDerivedStateFromProps(prps,state)
会因为props和state发生了改变而调用,会在初始化挂载及后续更新时都会被调用,它应返回一个对象来更新state,如果返回null则不更新任何内容。
用例:即state的值在任何时候都取决于props
例子:

 state = {
    data:[],
    width:0,
    height:0,
    pieName:'dayElectric',
  }

  componentDidMount(): void {
    console.log('componentDidMount')
  }

  // 会在调用 render 方法之前调用,并且在初始挂载及后续更新时都会被调用
  static getDerivedStateFromProps(nextProps:RouteComponentProps<{type:string}>, prevState:any) {
    console.log('getDerivedStateFromProps',nextProps)
    var responeceDate:any[] =[];
    const winW = document.documentElement.clientWidth || document.body.clientWidth;
    const winH = document.documentElement.clientHeight || document.body.clientHeight;
    const width = winW/2;
    const height = winH/4;
    const {type} = nextProps;
    if(type === '0'){
      responeceDate = FloorData.dayElectric
    }else if(type === '1'){
      responeceDate = FloorData.monthElectric
    }else if(type === '2'){
      responeceDate = FloorData.yearElectric
    }
    return {//返回一个对象来更新 state,如果返回 null则不更新任何内容。
      data:responeceDate,
      width,height
    };
    // return null;
  }

  componentDidUpdate(prevProps: Readonly<RouteComponentProps<{ type: string }>>, prevState: Readonly<{}>, snapshot?: any): void {
    console.log('componentDidUpdate')
  }

  componentWillUnmount(): void {
    console.log('componentWillUnmount')
  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41

运行结果:
//第一次: getDerivedStateFromProps componentDidMount
//第二次更新:getDerivedStateFromProps componentDidUpdate
在这里插入图片描述

shouldComponentUpdate(nextProps,nextState)
根据 shouldComponentUpdate() 的返回值,判断 React 组件的输出是否受当前 state 或 props 更改的影响。默认行为是 state 每次发生变化组件都会重新渲染。
此方法仅作为性能优化的方式而存在。不要企图依靠此方法来“阻止”渲染,因为这可能会产生 bug。你应该考虑使用内置的 PureComponent 组件,而不是手动编写 shouldComponentUpdate()。PureComponent 会对 props 和 state 进行浅层比较,并减少了跳过必要更新的可能性。

在class组件中写了getDerivedStateFromProps()生命周期函数就不能同时写componentWillMount和componentWillUpdate生命周期,不然会报以下错误:
在这里插入图片描述警告:使用新的组件api的组件将不会调用不安全的遗留生命周期
这是因为React16.8及以上版本将getDerivedStateFromProps该生命周期函数代替了componentWillMount和componentWillUpdate生命周期

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/65948?site
推荐阅读
相关标签
  

闽ICP备14008679号