目录
static getDerivedStateFromProps(props,state)
static getDerivedStateFromProps(props,state)
shouldComponentUpdate(nextProps,nextState)
getSnapshotBeforeUpdate(prevProps,prevState)
componentDidUpdate(prevProps, prevState, snapshot)
static getDerivedStateFromError(error)
React生命周期方法
以下生命周期方法按写的先后顺序被调用。
挂载
当组件实例被创建并插入 DOM 中时调用。
contructor()
如果不初始化 state 或不进行方法绑定,则不需要为 React 组件实现构造函数。
一般只用于以下两种情况
- 通过给
this.state
赋值对象来初始化内部state。 - 为事件处理函数绑定实例。
constructor(props) {
super(props);
// 不要在这里调用 this.setState()
this.state = { counter: 0 };
this.handleClick = this.handleClick.bind(this);
}
注意
- 调用了super(props) 后才能在构造函数里使用props变量。
- 将props属性赋值给state后,props改变不会引起state的改变,应该在render函数中直接使用this.props.属性名。
static getDerivedStateFromProps(props,state)
在调用 render 方法之前调用,并且在初始挂载及后续更新时都会被调用。参数props,state都为更新后的内容,最后的返回的对象用于更新state。如果返回 null
则不更新任何内容。
render()
render()
方法是 class 组件中唯一必须实现的方法。
当 render
被调用时,它会检查 this.props
和 this.state
的变化并返回以下类型之一:
- React 元素。通常通过 JSX 创建。例如,
<div />
会被 React 渲染为 DOM 节点,<MyComponent />
会被 React 渲染为自定义组件,无论是<div />
还是<MyComponent />
均为 React 元素。 - 数组或 fragments。 用于返回多个元素。 Fragments相当于一个容器,但不用增加任何dom节点。
- Portals。可以渲染子节点到不同的 DOM 子树中。
Portals 提供了一种将子节点渲染到存在于父组件以外的 DOM 节点方法。本身react父子组件上dom的关系是包含关系,而portal可以将子组件的dom渲染到外层窗口,比如将dom渲染成兄弟关系。常用语对话框、悬浮卡以及提示框。
- 字符串或数值类型。它们在 DOM 中会被渲染为文本节点
- 布尔类型或
null
。什么都不渲染。(主要用于支持返回test && <Child />
的模式,其中 test 为布尔类型。)
componentDidMount()
会在组件挂载后(插入 DOM 树中)立即调用。这里可以调用 setState()
。它将触发额外渲染,但此渲染会发生在浏览器更新屏幕之前。如此保证了即使在 render()
两次调用的情况下,用户也不会看到中间状态。
更新
当组件的 props 或 state 发生变化时会触发更新。
static getDerivedStateFromProps(props,state)
同上
shouldComponentUpdate(nextProps,nextState)
根据函数的返回值判断是否更新组件,返回false时,后面的生命周期方法都不会执行了。
此时this.state、this.props还未改变,参数中的nextProps和nextState是将要改变成的值,默认返回true(更新组件)。
注意首次渲染(挂载时)或使用 forceUpdate()
时不会调用该方法。
render()
同上
getSnapshotBeforeUpdate(prevProps,prevState)
此时this.state、this.props已经改变了,参数中preProps、prevState是改变之前的值。 返回值为componentDidUpdate中的第三个参数。
用于组件能在发生更改之前从 DOM 中捕获一些信息(例如,滚动位置)。
componentDidUpdate(prevProps, prevState, snapshot)
参数见上getSnapshotBeforeUpdate。
注意:可以在 componentDidUpdate()
中直接调用 setState()
,但请注意它必须被包裹在一个条件语句里,正如上述的例子那样进行处理,否则会导致死循环。
卸载
当组件从 DOM 中移除时会调用。
componentWillUnmount()
组件卸载及销毁之前直接调用。在此方法中执行必要的清理操作,例如,清除 timer,取消网络请求或清除在 componentDidMount()
中创建的订阅等。
注意这里不应调用 setState()
,因为该组件将永远不会重新渲染。组件实例卸载后,将永远不会再挂载它。
函数组建中生命周期替代方法 useEffect
相当于componentDidMount
、componentDidUpdate
和componentWillUnmount
的组合体。
代替componentDidMount
传递一个空数组([])作为第二个参数,这个 Effect 将永远不会重复执行,因此可以达到componentDidMount
的效果。
function AComponent(){
React.useEffect(()=>{
console.log("componentDidMount");
},[]);
}
代替componentDidUpdate
不传第二个参数
function AComponent(props){
React.useEffect(()=>{
console.log("每次更新后对会执行");
});
}
代替 componentWillUnmount
useEffect
可以返回一个函数,该函数将在组件被卸载时的执行,可以等效于componentWillUnmount
。
function AComponent(){
React.useEffect(()=>{
return function cleanup() { console.log("组件被卸载componentWillUnmount")};
},[]);
}
生命周期错误处理方法
当渲染过程,生命周期,或子组件的构造函数中抛出错误时调用。
相关概念
纯函数
- 确定的输入,产生确定的输出,与执行次数、时间无关
- 不产生副作用
例子:const add=x=> x+1
副作用
具有不确定性的操作,你都可以理解为是不纯的,不纯的那么意味可能带来副作用。
常见副作用:
- 系统IO相关API
- Date.now()、Math.random()等不确定性方法
- 在函数体内修改函数体外变量的值
- 在函数体内修改函数参数的值
- 调用会产生副作用的函数
- http请求等
static getDerivedStateFromError(error)
在后代组件抛出错误后被调用。 它将抛出的错误作为error参数,并返回一个对象更新 state。
注意该方法会
在渲染
阶段调用,因此不允许出现副作用。理解为在render之前调用,有副作用的话可能会导致死循环。
componentDidCatch(error,info)
在后代组件抛出错误后被调用,用于记录错误。参数error为
抛出的错误,info为
带有 componentStack
key 的对象,其中包含有关组件引发错误的栈信息。
注意该方法在“提交”阶段被调用,因此允许执行副作用。render之后调用,不会导致死循环。
在开发模式下,错误会冒泡至 window
,这意味着任何 window.onerror
或 window.addEventListener('error', callback)
会中断这些已经被 componentDidCatch()
捕获的错误。
相反,在生产模式下,错误不会冒泡,这意味着任何根错误处理器只会接受那些没有显式地被 componentDidCatch()
捕获的错误。