Skip to content

Latest commit

 

History

History
85 lines (65 loc) · 2.29 KB

05.md

File metadata and controls

85 lines (65 loc) · 2.29 KB

React getDrivedStateFromProps

getDrivedStateFromProps

React 之前的版本有一個 lifecycle componentWillReceiveProps,主要是如果 props 有發生改變則會觸發此 lifecycle。但現在的 React 則拔掉了這個 lifecycle,取而代之的是 getDerivedStateFromProps。那是為什麼呢?原因是因為 React 團隊不希望使用者一直用 componentWillReceiveProps 這個 lifecycle,但他又太好用了,所以把它改為 getDerivedStateFromProps(名字變長也變臭...)

來看一下簡單的範例

class ChildComponent1 extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      display: `${this.props.counter} times`
    }
  }

  static getDerivedStateFromProps(props, state) {
        if (props.counter === 1) {
            return null
        }
        return {
            display: `${props.counter} times`
        };
  }

  render() {
    return (
      <h1>{this.state.display}</h1>
    )
  }
}

const App = () => {
  const [counter, setCounter] = useState(0);

  return (
    <div>
      <button onClick={() => { setCounter(counter + 1) }}>Click</button>
    <ChildComponent1 counter={counter} />
    </div>
  )
}

可以看到如果使用者按下 button 就會使 counter + 1,則 ChildComponent 就會把 counter 的值加上 times。

注意看到 ChildComponent

static getDerivedStateFromProps(props, state)

他是一個 static function 表示他沒有 this,也就不能存取任何 instance 的值。parameters 是 props、state。其中 props 是更新過後的 props,state 是本身 component state。

如果 state 有更改則必須回傳更改後的 state,不然就回傳 null。


跟 Hooks 比較

Hooks 其實也可以達到同樣的功能

const ChildComponent1 = (props) => {
  const [display, setDisplay] = useState(`${props.counter} times`);

  useEffect(() => {
    if (props.counter === 1) {
      return undefined;
    }
    return setDisplay(`${props.counter} times`)
  }, [props.counter])

  return (
    <h1>{display}</h1>
  )
}

只要使用 useEffect 配合 dependency array 放置你要監聽的值即可(props.counter)。這樣就可以達到跟用 getDerivedStateFromProps 相同效果,並且程式碼更簡單更易閱讀。


tags: React getDerivedStateFromProps