赞
踩
报错:超过最大更新深度。当组件在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}) }
修改后:
// 会在调用 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; }
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') }
运行结果:
//第一次: 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生命周期
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。