Giai đoạn updating có thể xảy ra khi state hoặc props bị thay đổi.

Các phương thức sau sẽ được lần lượt gọi trong giai đoạn cập nhật:

  1. getDerivedStateFromProps
  2. shouldComponentUpdate
  3. render
  4. getSnapshotBeforeUpdate
  5. componentDidUpdate

getDerivedStateFromProps

Tương tự như giai đoạn mounting, phương thức getDerivedStateFromProps sẽ được gọi với cùng mục đích khi quá trình cập nhật bắt đầu diễn ra.

shouldComponentUpdate

Phương thức này có giá trị trả về là kiểu boolean. Nếu giá trị trả về là true, component sẽ được re-render. Ngược lại, component sẽ không được re-render nếu giá trị trả về là false.

Có thể dùng phương thức này để ngăn chặn một số sự thay đổi trên giao diện. Chẳng hạn như khi một người chơi đạt được điểm tối đa thì sẽ ngưng không tăng điểm nữa:

import { Component } from "react"
 
class Game extends Component {
  constructor(props) {
    super(props)
    this.state = {
      point: 0,
    }
  }
 
  increasePoint = () => {
    this.setState({ point: this.state.point + 1 })
  }
 
  shouldComponentUpdate = (nextProps, nextState) => {
    return nextState.point > 10 ? false : true
  }
 
  render() {
    return (
      <div>
        <p>Player point {this.state.point}</p>
        <button onClick={this.increasePoint}>Increase</button>
      </div>
    )
  }
}

render

Tương tự ở giai đoạn mounting, component sẽ được render lại một lần nữa trong giai đoạn update nếu có sự thay đổi về state hay props.

componentDidUpdate

Phương thức componentDidUpdate nhận hai đối số: prevPropsprevState, được gọi sau khi component được update.

Cũng với ví dụ về game ở trên, ta sẽ xuất ra dòng thông báo chúc mừng nếu người chơi đạt được số điểm tối đa như sau:

import { Component } from "react"
 
class Game extends Component {
  constructor(props) {
    super(props)
 
    this.state = {
      point: 0,
      greeting: "",
    }
  }
 
  increasePoint = () => {
    this.setState({ point: this.state.point + 1 })
  }
 
  shouldComponentUpdate = (nextProps, nextState) => {
    return nextState.point > 10 ? false : true
  }
 
  render() {
    return (
      <div>
        <p>Player point: {this.state.point}</p>
        <button onClick={this.increasePoint}>Increase</button>
        {this.state.greeting && <h1>{this.state.greeting}</h1>}
      </div>
    )
  }
 
  componentDidUpdate = (prevProps, prevState) => {
    if (prevState.point === 9) {
      this.setState({ greeting: "You won!" })
    }
  }
}

Note

Lý do mà ta không dùng phép so sánh this.state.point === 10 là vì có thể xảy ra lỗi gọi đệ quy vô hạn gây tràn stack.

Resources