组件的生命周期可分成三个状态:
- Mounting:已插入真实 DOM
- Updating:正在被重新渲染
- Unmounting:已移出真实 DOM
状态对应的钩子:
Mounting:componentWillMount() / componentDidMount()
Updating:componentWillReceiveProps() / shouldComponentUpdate() / componentWillUpdate() / componentDidUpdate()
Unmounting:componentWillUnmount()
其实严格上来讲在Mounting状态之前还有个初始化阶段,分别对应函数是constructor()、render()
<body>
<div id="box"></div>
<script src="react.15.6.js"></script>
<script src="react-dom.15.6.js"></script>
<script src="babel.js"></script>
<script src="https://unpkg.com/prop-types/prop-types.js"></script><!--自 React v15.5 起就被移除了。所以现在我们改用 prop-types 库代替。-->
<script type="text/babel">
class Message extends React.Component{
//初始化阶段执行:1.constructor 2.componentWillMount 3.render 4.componentDidMount
constructor(){//1
super();
console.log("constructor");
this.state = {
msg: "大吉大利!今晚吃鸡!"
}
}
componentWillMount(){//2 (组件将要被插入真实的dom之前)
console.log("componentWillMount")
}
//已插入真实DOM进入(mounting)状态
render(){//初始化(mounting)时:1 被重新渲染(updating)时:3
console.log("render");
return (
<div>
<p>{this.props.name}:{this.state.msg}</p>
<button onClick={this.changeCon.bind(this)}>换一句</button>
</div>
)
}
componentDidMount(){//2 (组件已经被插入到真实的dom,在这里调用异步在修改状态,做dom操作)
console.log("componentDidMount")
}
//当点击按钮触发changeCon之后进入重新渲染(updating)状态,执行:1.shouldComponentUpdate 2.componentWillUpdate 3.render 4.componentDidUpdate
shouldComponentUpdate(newProps, newState){//1 (当组件的props或者state发生改变之前,先判断永不允许调用render函数)
console.log("shouldComponentUpdate")
// if(typeof newProps.name === "string")
return true;
}
componentWillUpdate(){//2 (render函数被调用之前)
console.log("componentWillUpdate")
}
componentDidUpdate(){//4 (render函数被调用之后)
console.log("componentDidUpdate")
}
//当子组件中的按钮被点击触发changeName后执行componentWillReceiveProps,再次进入重新渲染(updating)状态
componentWillReceiveProps(){//1 (当组件接受到新props的时候)
console.log("componentWillReceiveProps")
}
componentWillUnmount(){//组件将要被移出真实DOM的时候
//...
}
changeCon(event){
console.log(event.target);
this.setState({msg: "GEME IS OVER!"})
}
}
Message.propTypes = {//key,验证的属性 ,value,验证的方式
name: PropTypes.string//number、oneOfType、oneOf、isRequired、、、
}
class Name extends React.Component{
constructor(){
super();
this.state = {
name: "阿林"
}
}
render(){
console.log("父---rander") //初始化的时候先执行父组件的初始化,从而进入到子组件的初始化,对于事件,是从那个组件中触发,就从那个组件开始执行
return (
<div>
<Message name={this.state.name}></Message>
<button onClick={(e)=>this.changeName(e)}>换个名字</button>
</div>
)
}
componentWillUpdate(){
console.log("父---componentWillUpdate");
}
componentDidUpdate(){
console.log("父---componentDidUpdate");
}
changeName(event){
console.log(event.target)
this.setState({name: "林哥"})
}
}
ReactDOM.render(<Name></Name>, document.querySelector("#box"))
</script>
</body>
输出结果:
初始化阶段到Mounting状态:
点击子组件的换一句按钮(接着打印):
再点击父组件的换个名字按钮(接着打印):