react v16.3終於出來了,最大的變更莫過於生命週期去掉了如下三個html
同時爲了彌補失去上面三個週期的不足又加了兩個前端
固然,這個更替是緩慢的,在整個16版本里都能無障礙的使用舊的三生命週期,但值得注意的是,舊的生命週期(unsafe)不能和新的生命週期同時出如今一個組件,不然會報錯「你使用了一個不安全的生命週期」。react
舊的生命週期十分完整,基本能夠捕捉到組件更新的每個state/props/ref,沒有什從邏輯上的毛病。安全
可是架不住官方本身搞事情,react打算在17版本推出新的Async Rendering,提出一種可被打斷的生命週期,而能夠被打斷的階段正是實際dom掛載以前的虛擬dom構建階段,也就是要被去掉的三個生命週期。bash
生命週期一旦被打斷,下次恢復的時候又會再跑一次以前的生命週期,所以componentWillMount,componentWillReceiveProps, componentWillUpdate都不能保證只在掛載/拿到props/狀態變化的時候刷新一次了,因此這三個方法被標記爲不安全。markdown
class Example extends React.Component {
static getDerivedStateFromProps(nextProps, prevState) {
// 沒錯,這是一個static
}
}
複製代碼
class Example extends React.Component {
getSnapshotBeforeUpdate(prevProps, prevState) {
// ...
}
}
複製代碼
初始化state — Initializing statedom
請求數據 — Fetching external data異步
添加事件監聽 — Adding event listeners (or subscriptions)async
根據props更新state — Updating state based on propside
if (this.props.currentRow !== nextProps.currentRow) { ... } 複製代碼
取而代之的是,額外寫一個state來記錄上一個props (` ^ ‘)
if (nextProps.currentRow !== prevState.lastRow) { return { ... lastRow: nextProps.currentRow, }; // 不更新state return null } 複製代碼
觸發請求 — Invoking external callbacks
props更新引發的反作用 — Side effects on props change
// 在didUpdate中根據props更新的確很不適應 // props變了也是能夠觸發update的 componentDidUpdate(prevProps, prevState) { if (this.props.isVisible !== prevProps.isVisible) { logVisibleChange(this.props.isVisible); } } 複製代碼
props更新時從新請求 — Fetching external data when props change
// old componentWillReceiveProps(nextProps) { if (nextProps.id !== this.props.id) { this.setState({externalData: null}); this._loadAsyncData(nextProps.id); } } 複製代碼
// new static getDerivedStateFromProps(nextProps, prevState) { // Store prevId in state so we can compare when props change. if (nextProps.id !== prevState.prevId) { return { externalData: null, prevId: nextProps.id, }; } // No state update necessary return null; } componentDidUpdate(prevProps, prevState) { if (this.state.externalData === null) { this._loadAsyncData(this.props.id); } } 複製代碼
在更新前記錄原來的dom節點屬性 — Reading DOM properties before an update
static getDerivedStateFromProps(nextProps, prevState) { 4. Updating state based on props 7. Fetching external data when props change // Clear out previously-loaded data so we dont render stale stuff } constructor() { 1. Initializing state } componentWillMount() { // 1. Initializing state // 2. Fetching external data // 3. Adding event listeners (or subscriptions) } componentDidMount() { 2. Fetching external data 3. Adding event listeners (or subscriptions) } componentWillReceiveProps() { // 4. Updating state based on props // 6. Side effects on props change // 7. Fetching external data when props change } shouldComponentUpdate() { } componentWillUpdate(nextProps, nextState) { // 5. Invoking external callbacks // 8. Reading DOM properties before an update } render() { } getSnapshotBeforeUpdate(prevProps, prevState) { 8. Reading DOM properties before an update } componentDidUpdate(prevProps, prevState, snapshot) { 5. Invoking external callbacks 6. Side effects on props change } componentWillUnmount() { } 複製代碼
上面的內容基本就是結合個人一些經驗半翻譯半總結,有不許確的地方歡迎指正。
對更多細節感興趣的話能夠去看官方文檔,https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html
對async-rendering或者對dan小哥哥感興趣的話能夠去看看他在前端大會上的一段小演示:https://reactjs.org/blog/2018/03/01/sneak-peek-beyond-react-16.html