v16.0前的周期.
componentWillMount,render,componentDidMount
componentWillMount:
在组件挂载到DOM前调用,且只会被调用一次,以后组件更新不调用,整个生命周期只调用一次,可以修改第一次state的值,也可以把写在这边的内容提前到constructor()中,所以项目中很少用。
render
创建虚拟dom,进行diff算法,更新dom树都在此进行。此时就不能更改state了。
componentDidMount()
组件渲染之后调用,只调用一次
componentWillReceiveProps(nextProps)
在接收到新的prop时被调用.这个方法在初始化render时不会被调用。
就如,初始化时候,给字元素传了新的props.content,但是子组件还是会展示,子组件自己的state里面的state.content,如果没有设置,那么展示空.但是在我传入的值变了的时候,就会展示为传入进去的值.
componentWillReceiveProps 在 render之前
同时componentWillReceiveProps)中调用 this.setState()
将不会引起第二次渲染。
shouldComponentUpdate(nextStates)
返回一个布尔值。在组件接收到新的props或者state时被调用。在初始化时或者使用forceUpdate时不被调用。
在setstate的时候,就得要判断nextProps.xxx != this.props.xxx
ornextState.xxx != this.state.xxx
通过返回True或者false来确定是不是把改变的值放到render里渲染.以此可用来减少组件的不必要渲染,优化组件性能。
componentWillUpdate(nextProps, nextState)
在组件接收到新的props或者state但还没有render时被调用。在初始化时不会被调用。
在这边可执行一些组件更新发生前的工作
componentDidUpdate(nextProps, nextState)
在组件完成更新后立即调用。可以操作组件更新的DOM.在初始化时不会被调用。
prevProps和prevState这两个参数指的是组件更新前的props和state
componentWillUnmount
此方法在组件被卸载前调用,可以在这里执行一些清理工作,比如清楚组件中使用的定时器,清楚componentDidMount中手动创建的DOM元素等,以避免引起内存泄漏。
v16.4的生命周期.
getDerivedStateFromProps
derived 英[dɪˈraɪvd]
从props中获取state,在组件创建时和更新时的render方法之前调用,它应该返回一个对象来更新状态,或者返回null来不更新任何内容。
是一个静态函数,也就是这个函数不能通过this访问到class的属性,也并不推荐直接访问属性。如果props传入的内容不需要影响到你的state,那么就需要返回一个null,和componentWillReceiveProps有点联系.
static getDerivedStateFromProps(nextProps, prevState) {
const {type} = nextProps;
// 当传入的type发生变化的时候,更新state
if (type !== prevState.type) {
return {
type,
};
}
// 否则,对于state不进行任何操作
return null; }
getSnapshotBeforeUpdate
被调用于render之后,可以读取但无法使用DOM的时候。它使您的组件可以在 可能更改之前从DOM捕获一些信息(例如滚动位置)。
此生命周期返回的任何值都将作为参数传递给componentDidUpdate()。
getSnapshotBeforeUpdate(prevProps, prevState) {
//我们是否要添加新的 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;
}
}
新特性:
1、render 支持返回数组和字符串,render方法支持直接返回string,number,boolean,null,portal,以及fragments(带有key属性的数组),这可以在一定程度上减少页面的DOM层级。
2、**使用Error Boundary处理错误组件,**我们可以在容易出错的组件外使用ErrorBoundary将它包裹起来、
当某个组件发生错误时,我们可以通过Error Boundary捕获到错误并对错误做优雅处理,如使用Error Boundary提供的内容替代错误组件,之前,一旦某个组件发生错误,整个组件树将会从根节点被unmount下来。
3、支持自定义DOM属性,在之前的版本中,React会忽略无法识别的HTML和SVG属性,自定义属性只能通过data-*形式添加,现在它会把这些属性直接传递给DOM(这个改动让React可以去掉属性白名单,从而减少了文件大小),不过有些写法仍然是无效的。如DOM传递的自定义属性是函数类型或event handler时,依然会被React忽略
4、setState传入null时不会再触发更新
5、**.更好的服务器端渲染,**现在提供一种流模式streaming,可以更快地把渲染的字节发送到客户端
6 使用createPortal将组件渲染到当前组件树之外,Portals机制提供了一种最直接的方式可以把一个子组件渲染到父组件渲染的DOM树之外,带来的一个特性就是,在子组件产生的event依然可以被React父组件捕获,但在DOM结构中,它却不是你的父组件。对于组件组织,代码切割来说,这是一个很好的属性。
render() {
return ReactDOM.createPortal(
×
{this.props.children}
,
this.container
)
}
}
使用是:
render() {
return (
hello world!
{this.state.overlayActive &&
overlay content }
);
}
}