Vòng đời của một Component trong ReactJs với ES6

Có thể nói khái niệm component trong React là một trong những thành phần quan trọng nhất của React. Do vậy, việc hiểu rõ vòng đời của một component sẽ giúp chúng ta hiểu rõ hơn về React.

Danh sách các hàm/phương thức của compopent

Danh sách các method của một component.

import React, {Component, PropTypes} from 'react';

class User extends Component {
    constructor (props) {
        super (props)
        // Thực hiện việc thiết lập state cho component
        // Việc sử dụng super(props) là để có thể sử dụng this.props trong phạm vi hàm constructor này
    }
  
    componentWillMount () {
        // Thực hiện một số tác vụ
        // Chỉ thực hiện 1 lần duy nhất
    }
  
    componentDidMount () {
        // Thực hiện một số tác vụ, chỉ thực hiện 1 lần duy nhất
        // Rất hữu dụng khi làm việc thêm với Map, bởi vì map chỉ render được  khi có node (id) trong DOM  
        // Tóm lại, hàm này được gọi để thông báo component đã tồn tại trên DOM, 
        // từ đó các thao tác trên DOM sẽ có thể thực hiện bình thường đối với component này
    }
  
    componentWillUnmount () {
        // Thực hiện một lần duy nhất, khi component sẽ unmount
        // Hữu dụng khi cần xoá các timer không còn sử dụng
    }
  
    componentWillReceiveProps (nextProps) {
        // Hàm này thực hiện liên tục mỗi khi props thay đổi
        // (1) Sử dụng để thay đổi trạng thái (state) của component phụ thuộc props
        // (2) Sử dụng các kết quả, khởi tạo biến có tính chất async. Ví dụ: Khởi tạo Google Map Api, đây là quá trình async,
        // do vậy, ta không thể biết được khi nào khởi tạo xong, thì khi khởi tạo xong có thể truyền xuống component thông qua
        // props, và từ đó ta có thể khởi tạo các dịch vụ khác.
        // Example:
        //# if (nextProps.mapLoaded) { //props.mapLoaded khởi tạo false
        //#     let googleMaps = this.props.googleMaps ||
        //#         (window.google && // eslint-disable-line no-extra-parens
        //#         window.google.maps) ||
        //#         this.googleMaps;

        //#     if (!googleMaps) {
        //#         console.error(// eslint-disable-line no-console
        //#         'Google map api was not found in the page.');
        //#         return;
        //#     }
        //#     this.googleMaps = googleMaps;

        //#     this.autocompleteService = new googleMaps.places.AutocompleteService();
        //#     this.geocoder = new googleMaps.Geocoder();
        //# } 
    }
  
    shouldComponentUpdate (nextProps, nextState) {
        // Thực hiện khi state và props thay đổi
        // Trả về kết quả true/false, ta sẽ cần sử dụng đến hàm này để xử lý xem có cần update component không
    }
  
    componentWillUpdate (nextProps, nextState) {
        // Thực hiện dựa vào kết quả của hàm trên (shouldComponentUpdate)
        // Nếu hàm trên trả về false, thì React sẽ không gọi hàm này
    }
  
    componentDidUpdate(prevProps, prevState) {
        // Thực hiện sau khi component được render lại, từ kết quả của componentWillUpdate
    }
  
  render() {
    return (
      <div>
        // thực hiện việc render
      </div>
    );
  }
}

User.propTypes = {
  //Khai báo kiểu biến cho props
};
User.defaultProps = {
  //Khai báo giá trị mặc định cho props
}
export default User;

Như vậy, class phía trên đã liệt kê toàn bộ phương thức của Component, tiếp theo chúng ta sẽ xem xét các sự kiện tương tác ảnh hưởng đến Component như thế nào.

Vòng đời của component

Khởi tạo Component

Lần lượt các hành động sau để khởi tạo component:

  • Khởi tạo Class (đã thừa kế từ class Component của React)
  • Khởi tạo giá trị mặc định cho Props (defaultProps)
  • Khởi tạo giá trị mặc định cho State (trong hàm constuctor)
  • Gọi hàm componentWillMount()
  • Gọi hàm render()
  • Gọi hàm componentDidMount()

Khi State thay đổi

  • Cập nhật giá trị cho state
  • Gọi hàm shouldComponentUpdate()
  • Gọi hàm componentWillUpdate() – với điều kiện hàm trên return true
  • Gọi hàm render()
  • Gọi hàm componentDidUpdate()

Khi Props thay đổi

  • Cập nhật giá trị cho props
  • Gọi hàm componentWillReceiveProps()
  • Gọi hàm shouldComponentUpdate()
  • Gọi hàm componentWillUpdate() – với điều kiện hàm trên return true
  • Gọi hàm render()
  • Gọi hàm componetDidUpdate()

Khi Unmount component

  • Gọi hàm componentWillUnmount()

Nói thêm về setState

Trong React, ta chỉ khởi tạo giá trị this.state một lần duy nhất, sau khi khởi tạo xong, nếu muốn cập nhật this.state, ta phải dùng hàm this.setState.

Khi sử dụng this.setState, chính là kích hoạt danh sách các phương thức thuộc vòng đời của component (shouldComponentUpdate, componentWillUpdate, render, componentDidUpdate). Và cũng luôn nhớ rằng, this.setState là hàm async, nên truy cập this.state ngay sau khi setState sẽ không nhận được giá trị mới của this.state.

Hãy thử xem đoạn code sau:

componentWillReceiveProps(nextProps){
      this.setState(nextProps)
      console.log(this.state) //=> in ra giá trị cũ của state, không được cập nhật nextProps
}

Để khắc phục khi ta muốn thực hiện thêm 1 hành động nào đó như lưu log, tracking, thông báo… thì sử dụng hàm callback như sau:

componentWillReceiveProps(nextProps){
  this.setState(nextProps, ()=>{
    this.updateDatabase(this.state)
  })
}

Ta có thể sử dụng cách viết callback sau khi setState ở bất cứ đâu trong component ngoại trừ hàm render()

Tài liệu tham khảo: http://facebook.github.io/react/docs/component-specs.html http://busypeoples.github.io/post/react-component-lifecycle/