1. 程式人生 > >a dive in react lifecycle

a dive in react lifecycle

背景:我在react文件裡找生命週期的圖,居然沒有,不敢相信我是在推特上找到的。。。

正文

react v16.3 新生命週期:

  • static getDerivedStateFromProps
  • getSnapshotBeforeUpdata

1: getDerivedStateFromProps, 在render之前,返回一個obj更新state,或者null不更新state, 這個生命週期的使用場景是:state根據props變化。

 static getDerivedStateFromProps(nextProps: SearchProps, prevState: SearchState) {
    const { location } 
= nextProps const state = location.state if (state && (state.keyword !== prevState.keyword)) { const { keyword } = statereturn { pageState: 0, employee: { hit: 0, count: 0, data: [], currentOffset: 0 }, document: { hit:
0, count: 0, data: [], currentOffset: 0 }, keyword, needExact: false } } return null }

2: getSnapshotBeforeUpdata  觸發時間:在實際dom掛載之前,虛擬dom構建之後。返回的任何資料或者null,都將作為componentDidUpdate()的引數。

 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; } }

建議用法總結請移步:https://juejin.im/post/5aca20c96fb9a028d700e1ce

這裡拷貝一個我用到的一種情況:props更新時重新請求

// 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);
    }
  }

我的使用:

  componentDidUpdate(prevProps: SearchProps, prevState: SearchState) {
    const { keyword, needExact } = this.state
    if (keyword && (keyword !== prevState.keyword)) {  // 上一次的state和這一次的對比,如果需要,就進行fetch資料,並setstate。其中this.state就是getDerivedStateFromProps返回的 更新後的state
      if (needExact) {
        this._fetchExactData(this.state.keyword)
        this.setState({
          needExact: false
        })
      } else {
        Promise.all([this._fetchInitData('document'), this._fetchInitData('employee')])
          .then(values => {
            let pageState = 0
            const { state } = this.props.location 
            if (state && state.type) {
              pageState = state.type
            } else if (!values[1] && values[0]) {
              pageState = 1
            }
            this.setState({
              pageState,
            })
          })
      }
    }
  }

最後,記錄一個小知識點:

由於state變化,需要出發請求資料的,在componentDidUpdate中進行。