Reactv16.8.6生命周期函数
组件生命周期函数
react 主动调用的方法,也可重写这些方法
当组件实例被创建并插入 dom
中时,其生命周期调用顺序如下:
constructor(props)
如果不需要初始化 state 或 不进行方法绑定,则不需要使用该方法
在组件挂载之前会先调用该方法,在实现构造函数时必须先调用super(props)
方法,否则会出现bug
通常,构造函数仅用于两种情况:1. 初始化 state
2. 为事件处理函数绑定实例
在该方法中不要使用 setstate()
方法,在其他方法中使用setstate()
改变 state
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方法可以返回多个元素
-
portals
:可以渲染子节点到不同的dom子树汇中 - 字符串或数值类型: 在dom中会被渲染为文本节点、
-
boolean 或 null
:什么都不渲染
render方法最好为纯函数,即在不修改组件 state
情况下,每次调用时都返回相同的结果,并且不会直接与浏览器交互
如果要和浏览器交互,可以在其他生命周期函数中执行,注意:
shoouldcomponentupdate
方法中返回false,将不会调用render方法
class example extemds react.component{ shouldcomponentupdate(nextprops, nextstate){ return false } render(){ // 不会执行 <div>owen</div> } }
componentdidmount()
此方法会在组件挂载后(插入dom树中)调用,初始化的数据的好地方
组件的 props
或 state
发生变化会触发更新。组件更新的生命周期调用顺序如下:
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> ); } }
参考资料:react官网
下一篇: 洛谷 CF894A QAQ