组件从被创建到被销毁的过程称为组件的生命周期
在不同的生命周期阶段提供不同的生命周期方法
让开发者可以在组件的生命周期过程中更好地控制组件的行为。
通常,组件的生命周期可以被分为三个阶段:挂载阶段、更新阶段、卸载阶段
- mounting
- 创建虚拟DOM,渲染UI
- updating
- 更新虚拟DOM,重新渲染UI
- unmounting
- 删除虚拟DOM,删除UI
将界面UI和它的逻辑封装到同一个JS文件中。组件是React的核心,
根据组件的外部接口props和内部接口state完成自身UI的渲染。
使用组件时,需要理解它的生命周期,
借助不同的生命周期方法,组件可以实现复杂逻辑。
组件在渲染列表数据时,要注意key的使用,
在事件处理时,要注意事件名和事件处理函数的写法。
class App extends React.Component<Props, State> {
// 1 生命周期第一阶段:初始化,初始化组件 state
constructor(props) {
super(props)
this.state = {
dataSource: []
}
}
// 2 在组件创建好 DOM元素后,挂载页面的时候调用
componentDidMount() {
fetch('url').then().then()
}
// 生命周期的第二个阶段:更新 组件接收到一个新的 prop时被调用
componentWillReceiveProps() {} // 废弃,用 getDerivedStateFromProps代替
static getDerivedStateFromProps(nextProps, prevState) { }
// true更新,false不更新
shouldComponentUpdate(nextProps, nextState) {
return nextState.name !== this.state.name
}
// 组件更新后调用
componentDidUpdate() {}
// 生命周期的第三个阶段:销毁,当做析构函数 destructor来使用
// 销毁组件,避免内存泄漏
componentWillmount() {}
}
class组件的生命周期
constructor
组件被创建时,会首先调用组件的构造方法 constructor。
constructo构造方法接收一个props参数,
props是从父组件中传入的属性对象,
如果父组件中没有传入属性而组件自身定义了默认属性,那么这个props指向的就是组件的默认属性。
必须在这个方法中首先调用 super(props)才能保证props被传入组件中。
constructor通常用于初始化组件的state以及绑定事件处理方法等工作
render
组件时唯一必要的方法,组件的其他生命周期方法都可以省略
在 render方法中,根据组件的props和state返回一个React元素
componentDidMount
在组件被挂载到DOM后调用,且只会被调用一次。
这时候已经可以获取到DOM结构,因此依赖DOM节点的操作可以放到这个方法中。
这个方法通常还会用于向服务器端请求数据。在这个方法中调用
this.setState会引起组件的重新渲染
componentDidUpdate
初始化
在React Fiber中,第一阶段中的生命周期函数在一次加载和更新过程中可能会被多次调用!
子组件初始化
子组件的生命周期
挂载时
更新时
卸载时
props
执行初始化,并被挂载到DOM中,完成组件的第一次渲染。依次调用的生命周期方法有:
- constructor
- componentWillMount
- render
- componentDidMount
getDefaultProps
getInitialState
componentWillMount // 常用的,ajax请求数据,SSR不能用
->
UNSAFE_componentWillMount
render
componentDidMount // 常用的,ajax请求数据
componentWillReceiveProps
->
UNSAFE_componentWillReceiveProps
shouldComponentUpdate
componentWillUpdate
->
UNSAFE_componentWillUpdate
componentDidUpdate
componentWillUnmount
第一阶段可能会调用下面这些生命周期函数,说是“可能会调用”是因为不同生命周期调用的函数不同
componentWillMount
componentWillReceiveProps
shouldComponentUpdate
componentWillUpdate
生命周期函数则会在第二阶段调用
componentDidMount
componentDidUpdate
componentWillUnmount
更新时
组件被挂载到DOM后,组件的props或state可以引起组件更新。
props引起的组件更新,本质上是由渲染该组件的父组件引起的,
也就是当父组件的render方法被调用时,组件会发生更新过程,
这个时候,组件props的值可能发生改变,也可能没有改变,
因为父组件可以使用相同的对象或值为组件的props赋值。
但是,无论props是否改变,父组件render方法每一次调用,都会导致组件更新。
State引起的组件更新,是通过调用this.setState修改组件state来触发的。
组件更新阶段,依次调用的生命周期方法有:
- componentWillReceiveProps
- shouldComponentUpdate
- componentWillUpdate
- render
- componentDidUpdate
componentWillReceiveProps
componentWillReceiveProps只在props引起的组件更新过程中,才会被调用。
State引起的组件更新并不会触发 componentWillReceiveProps方法的执行。
方法的参数nextProps是父组件传递给当前组件的新的props。
但父组件render方法的调用
并不能保证传递给子组件的props发生变化,
也就是说nextProps的值可能和子组件当前props的值相等,因此往往需要比较nextProps和this.props
来决定是否执行props发生变化后的逻辑,
比如根据新的props调用this.setState触发组件的重新渲染
componentWillReceiveProps(nextProps) {
}