react的一些函数的官方介绍
函数 / 方法
ES6中React组件是用class来定义的,关于class的知识可以看阮一峰的es6的相关介绍, 当然,如果你英文不错也可以看React的官方介绍
// 定义一个TodoList的React组件,通过继承React.Component来实现
class TodoList extends React.Component {
...
}
class的定义方法
constructor(props, context) {
super(props);
this.state = {};
}
class中的构造器,主要功能是初始化一些变量(state等)并继承父类(父组件)的属性,需要注意的是React组件中如果有定义constructor函数就必须要写super()
,而constructor里面如果要使用this.props的话就要super(props)
,但是就算不写也不影响其他函数使用props因为React会自动传入。
render() {
return (
);
}
渲染页面,由于setState会触发render,所以不要在这里面setState。
void componentWillMount() // unsafe, 16.4废弃,constructor的执行过程与之相似
在组件挂载之前调用一次。
void componentDidMount()
在组件挂载之后调用一次。
void componentWillReceiveProps(nextProps) // unsafe, 16.4废弃
父组件发生更新时被调用(不管props有没有更新,也不管父子组件之间有没有数据交换)
bool shouldComponentUpdate(nextProps, nextState)
判断是否要调用render,默认返回true,每次setState/componentWillReceiveProps触发后调用,在比较复杂的应用里,有一些数据的改变并不影响界面展示,可以在这里做判断,优化渲染效率。
void componentWillUpdate(nextProps, nextState) // unsafe 16.4废弃,可以用getDerivedStateFromProps替代
组件将要更新之前调用,
static getDerivedStateFromProps(props, state) // 16.3++版本
组件更新(render)之前调用,第一次初始化和无论何种方式更新组件都会调用此方法, 要注意的是 要加static
getSnapshotBeforeUpdate() // 16.3++版本
页面之前的dom元素还没改变之前调用,具体周期是render之后componentDidUpdate之前,返回的值可以被componentDidUpdate接收
例如:
class ScrollingList extends React.Component {
constructor(props) {
super(props);
this.listRef = React.createRef();
}
getSnapshotBeforeUpdate(prevProps, prevState) {
// Are we adding new items to the list?
// Capture the scroll position so we can adjust scroll later.
if (prevProps.list.length < this.props.list.length) {
const list = this.listRef.current;
return list.scrollHeight - list.scrollTop;
}
return null;
}
componentDidUpdate(prevProps, prevState, snapshot) {
// If we have a snapshot value, we've just added new items.
// Adjust scroll so these new items don't push the old ones out of view.
// (snapshot here is the value returned from getSnapshotBeforeUpdate)
if (snapshot !== null) {
const list = this.listRef.current;
list.scrollTop = list.scrollHeight - snapshot;
}
}
render() {
return (
{/* ...contents... */}
);
}
}
void componentDidUpdate()
组件更新之后调用,除了首次render之后调用componentDidMount,其它render结束之后都是调用componentDidUpdate。
void componentWillUnmount()
组件被卸载的时候调用。一般在componentDidMount里面注册的事件需要在这里删除。
void componentDidCatch(error, info)
可以捕获其子组件树和当前生命周期里面的任何js错误,然后可以通过setState()显示错误的UI界面
更新方式
- 首次渲染Initial Render
- 调用this.setState (并不是一次setState会触发一次render,React可能会合并操作,再一次性进行render)
- 父组件发生更新(一般就是props发生改变,但是就算props没有改变或者父子组件之间没有数据交换也会触发render)
- 调用this.forceUpdate
React16.3版本以前的
React16.4版本以后的
一个React组件生命周期的测试例子
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
class TestLifeCircle extends Component {
constructor() {
super();
alert('constructor');
this.state = { name: 'Li Si' };
}
// componentWillMount() {
// alert('componentWillMount');
// }
componentDidMount() {
alert('componentDidMount');
}
componentWillUnmount() {
alert('componentWillUnmount')
}
// componentWillReceiveProps(nextProps) {
// alert('componentWillReceiveProps');
// }
shouldComponentUpdate(nextProps, nextState) {
alert('shouldComponentUpdate');
return true;
}
// componentWillUpdate() {
// alert('componentWillUpdate');
// }
componentDidUpdate() {
alert('componentDidUpdate');
}
static getDerivedStateFromProps(props, state) {
console.log('getDerivedStateFromProps: ', props, state);
alert('getDerivedStateFromProps');
}
getSnapshotBeforeUpdate() {
alert('getSnapshotBeforeUpdate');
}
setTheState() {
this.setState({ name: 'Zhang San' });
}
forceLifeCycleUpdate() {
this.forceUpdate();
}
render() {
alert('render');
const { name } = this.state;
return (
Welcome {name}!
);
}
}
class App extends Component {
constructor() {
super();
this.state = {};
}
parentSetState() {
this.refs.testLifeCircle.setTheState();
}
propsUpdate() {
this.setState({ data: '123' });
}
parentForceUpdate() {
this.refs.testLifeCircle.forceLifeCycleUpdate();
}
unmount() {
ReactDOM.unmountComponentAtNode(document.getElementById("app"));
}
render() {
return (
);
}
}
ReactDom.render(
,
document.getElementById('app')
);
参考:React组件生命周期小结