组件是一个类,当它被使用的时候实例化,然后挂载到页面中。
1.组件第一次加载
组件第一次加载生命周期的执行顺序:
- defaultProps
- constructor
- componentWillMount
- render
- componentDidMount
export default class Counter extends Component {
//如果传递值了使用传递值,没有传值使用默认值:默认属性对象
static defaultProps = {
count: 0
}
constructor(props) {
console.log('constructor');
super(props);
this.state = { count: props.count };//初始化默认状态对象
}
componentWillMount() {
console.log('1.组件将要挂载 componentWillMount');
}
render() {
console.log('2.render 挂载');
return (
<div>
父计数器:{this.state.count}
</div>
)
}
//组件挂载完成
componentDidMount() {
console.log('3.componentDidMount 组件挂载完毕');
}
}
复制代码
输出
constructor
1.组件将要挂载 componentWillMount
2.render 挂载
3.componentDidMount 组件挂载完毕
复制代码
2.修改状态
添加一个button按钮去修改计数器的state,查看状态更新后组件声明周期的流程
- shouldComponentUpdate
- componentWillUpdate
- render
- componentDidUpdate
export default class Counter extends Component {
//如果传递值了使用传递值,没有传值使用默认值:默认属性对象
static defaultProps = {
count: 0
}
constructor(props) {
console.log('constructor');
super(props);
this.state = { count: props.count };//初始化默认状态对象
}
componentWillMount() {
console.log('1.组件将要挂载 componentWillMount');
}
//当需要旧状态时,使用传入一个方法,参数为旧状态这种形式
handleClick = () => {
this.setState(prevState => ({
count: prevState.count + 1
}));
}
//询问组件是否要被更新,当一个组件的属性或者状态只要有一个发生了改变 ,默认就会重新渲染。返回true则组件更新,返回false则组件不更新
shouldComponentUpdate(nextProps, nextState) {
if (nextState.count < 10) {
return true;
} else {
return false;
}
}
componentWillUpdate() {
console.log('componentWillUpdate');
}
componentDidUpdate() {
console.log('componentDidUpdate');
}
render() {
console.log('2.render 挂载');
return (
<div>
父计数器:{this.state.count}
<button onClick={this.handleClick}>+</button>
</div>
)
}
//组件挂载完成
componentDidMount() {
console.log('3.componentDidMount 组件挂载完毕');
}
}
复制代码
输出
constructor
1.组件将要挂载 componentWillMount
2.render 挂载
3.componentDidMount 组件挂载完毕
componentWillUpdate
2.render 挂载
componentDidUpdate
复制代码
3.接收新的属性
组件内属性不可以更改,只能通过父组件传递。
父组件:
export default class Counter extends Component {
//如果传递值了使用传递值,没有传值使用默认值:默认属性对象
static defaultProps = {
count: 0
}
constructor(props) {
console.log('constructor');
super(props);
this.state = { count: props.count };//初始化默认状态对象
}
componentWillMount() {
console.log('1.组件将要挂载 componentWillMount');
}
handleClick = () => {
this.setState(prevState => ({
count: prevState.count + 1
}));
}
//询问组件是否要被更新,当一个组件的属性或者状态只要有一个发生了改变 ,默认就会重新渲染
shouldComponentUpdate(nextProps, nextState) {
if (nextState.count < 10) {
return true;
} else {
return false;
}
}
componentWillUpdate() {
console.log('componentWillUpdate');
}
componentDidUpdate() {
console.log('componentDidUpdate');
}
render() {
console.log('2.render 挂载');
return (
<div>
父计数器:{this.state.count}
<button onClick={this.handleClick}>+</button>
//添加子组件 传递count属性
<SubCounter count={this.state.count} />
</div>
)
}
//组件挂载完成
componentDidMount() {
console.log('3.componentDidMount 组件挂载完毕');
}
}
复制代码
子组件
- componentWillReceiveProps
- shouldComponentUpdate
- componentWillUpdate
- componentDidUpdate
class SubCounter extends Component {
//当子组件将要接收到父组件传给它的新属性的时候
componentWillReceiveProps() {
console.log('SubCounter componentWillReceiveProps');
}
shouldComponentUpdate(nextProps, nextState) {
console.log('SubCounter shouldComponentUpdate');
if (nextProps.count <= 5) {
return true;
} else {
return false;
}
}
componentWillUpdate() {
console.log('SubCounter componentWillUpdate');
}
componentDidUpdate() {
console.log('SubCounter componentDidUpdate');
}
render() {
console.log('SubCounter render 挂载');
return (
<div>
子计数:{this.props.count}
</div>
)
}
}
复制代码
未点击加号输出:
constructor
1.组件将要挂载 componentWillMount
2.render 挂载
SubCounter render 挂载
3.componentDidMount 组件挂载完毕 //需要子组件加载完毕后父组件才会加载完毕
点击添加按钮 新增输出:
//先是父组件将要更新,然后渲染
componentWillUpdate
2.render 挂载
//子组件
SubCounter componentWillReceiveProps
SubCounter shouldComponentUpdate
SubCounter componentWillUpdate
SubCounter render 挂载
SubCounter componentDidUpdate
//父组件完成更新
componentDidUpdate
复制代码
4.组件的卸载
什么时候用到componentWillUnmount:
单页应用中,切换页面原组件需要销毁释放资源,如果原组件中有定时器等不能销毁时,需要在componentWillUnmount中清理资源占用,手动销毁定时器。
export default class Counter extends Component {
//默认属性对象
static defaultProps = {
count: 0
}
constructor(props) {
console.log('constructor');
super(props);
this.state = { count: props.count };//初始化默认状态对象
}
componentWillUnmount() {
window.clearInterval(this.timer);
console.log('componentWillUnmount');
}
destroy = () => {
//卸载组件的方法
ReactDOM.unmountComponentAtNode(document.querySelector('#root'));
}
render() {
return (
<div>
父计数器:{this.state.count}
<button onClick={this.destroy}>destroy</button>
</div>
)
}
//组件挂载完成
componentDidMount() {
console.log('3.componentDidMount 组件挂载完毕');
//如果不清定时器,组件卸载将要报错,因为组件卸载this这个当前组件已被销毁。
this.timer = window.setInterval(() => {
this.setState(prevState => ({
count: prevState.count + 1
}));
}, 1000);
}
}
复制代码