12/08/2018, 15:14

Vòng đời của component trong React

React đang phát triển rất mạnh mẽ dành được sự thu hút quan tâm của nhiều người. Trong react, có thể nói component là thành phần quan trọng nhất, mọi thứ trong react được xoay quanh component. Do vậy, hiểu rõ về component sẽ giúp chúng ta có được cái nhìn rõ ràng nhất về react. Lifecycle methods ...

React đang phát triển rất mạnh mẽ dành được sự thu hút quan tâm của nhiều người. Trong react, có thể nói component là thành phần quan trọng nhất, mọi thứ trong react được xoay quanh component. Do vậy, hiểu rõ về component sẽ giúp chúng ta có được cái nhìn rõ ràng nhất về react. Lifecycle methods là những method được gọi tại một thời điểm nào đó trong vòng đời của một component. Chúng ta có thể viết một lifecycle methods được gọi trước khi component được render trong lần đầu tiên. Hoặc được gọi sau khi component được render trong những lần sau. Chúng ta sẽ lần lượt tìm hiểu từng lifecycle method Có 3 loại lifecycle methods là: Mounting, Updating và Unmounting:

Một component thực hiện "mount" chỉ khi nó render trong lần đầu tiên. Có 3 mounting lifecycle methods:

  • componentWillMount
  • render
  • componentDidMount

Khi một component "mount" nó sẽ tự động gọi lần lượt 3 method trên, mounting lifecycle method đầu tiên được gọi là componentWillMount. Khi một component được render trong lần đầu tiên thì componentWillMount sẽ được gọi trước khi render. Ví dụ:

var React = require('react');
var ReactDOM = require('react-dom');

var Example = React.createClass({
  componentWillMount: function () {
    alert('componentWillMount sẽ được gọi ở đây');
  },

  render: function () {
    return <h1>Hello world</h1>;
  }
});

ReactDOM.render(
  <Example />,
  document.getElementById('app')
);	

setTimeout(function(){
  ReactDOM.render(
    <Example />,
    document.getElementById('app')
  );
}, 2000);

Ở đoạn code trên, khi chạy thì trong lần render đầu tiên, lần lượt sẽ bắn ra alert("componentWillMount sẽ được gọi ở đây"), sau đó màn hình hiển thị render text: Hello world. Từ những lần sau, khi render lại component Example, được gọi trong setTimeout thì alert sẽ không được gọi lại nữa.

Sau khi componentWinMount thực hiện xong, sẽ đến render(cho lần đầu tiên), và sau đó sẽ gọi method componentDidMount(), componentDidMount() được sử dụng rất nhiều. Nếu ứng dụng React của bạn đang sử dụng AJAX để fetch những dữ liệu khởi tạo từ một API thì componentDidMount là nơi để thực hiện lời gọi AJAX đó. Nói chung, componentDidMount là một nơi thích hợp để kết nối một ứng dụng React với một ứng dụng bên ngoài như một web API hay một javascript framework. componentDidMount cũng là nơi để các method set time như: setTimeout và setInterval.

var React = require('react');

var Example = React.createClass({
  componentDidlMount: function () {
    alert('component just finished mounting!');
  },

  render: function () {
    return <h1>Hello world</h1>;
  }
});

Sau khi component render lần đầu tiên, các lifecycle methods của Updating sẽ được gọi bắt đầu với lần render thứ hai. Với cơ chế automatic binding của mình thì chắc chắn các component sẽ được render nhiều lần trong ứng dụng của bạn. Có 5 method trong lifecycle updating:

  • componentWillReceiveProps
  • shouldComponentUpdate
  • componentWillUpdate
  • render
  • componentDidUpdate

Mỗi khi một instance của component được update, nó sẽ tự động gọi lần lượt 5 methods trên. Updating lifecycle methods đầu tiên là componentWillReceiveProps, khi một instance của component được update, componentWillReceiveProps sẽ được gọi trước khi render. Có một chú ý ở đây là: componentWillReceiveProps chỉ được gọi nếu component được nhận một prop:

// componentWillReceiveProps will get called here:
ReactDOM.render(
  <Example prop="myVal" />,
  document.getElementById('app')
);

// componentWillReceiveProps will NOT get called here:
ReactDOM.render(
  <Example />,
  document.getElementById('app')
);

componentWillReceiveProps tự động được truyền vào một argument, được gọi là nextProps, nextProps chính là giá trị preview của prop mà component sắp được nhận để render. Ví dụ

var React = require('react');

var Example = React.createClass({
  componentWillReceiveProps: function (nextProps) {
    alert("Check out the new props.text that "
    	+ "I'm about to get:  " + nextProps.text);
  },

  render: function () {
    return <h1>{this.props.text}</h1>;
  }
});


// The first render won't trigger
// componentWillReceiveProps:
ReactDOM.render(
	<Example text="Hello world" />,
	document.getElementById('app')
);

// After the first render, 
// subsequent renders will trigger
// componentWillReceiveProps:
setTimeout(function () {
	ReactDOM.render(
		<Example text="Hello world" />,
		document.getElementById('app')
	);
}, 1000);

giá trị của nextProps.text trong componentWillReceiveProps là "Hello world".

Updating lifecycle method thứ hai là shouldComponentUpdate. Khi một component update, shouldComponentUpdate sẽ được gọi sau componentWillReceiveProps nhưng vẫn trước render. Ví dụ:

var React = require('react');

var Example = React.createClass({
  getInitialState: function () {
    return { subtext: 'Put me in an <h2> please.' };
  },

  shouldComponentUpdate: function (nextProps, nextState) {
    if ((this.props.text == nextProps.text) && 
      (this.state.subtext == nextState.subtext)) {
      alert("Props and state haven't changed, so I'm not gonna update!");
      return false;
    } else {
      alert("Okay fine I will update.");
      return true;
    }
  },

  render: function () {
    return (
      <div>
        <h1>{this.props.text}</h1>
        <h2>{this.state.subtext}</h2>
      </div>
    );
  }
});

shouldComponentUpdate sẽ trả về true hoặc false. Nếu trả về true, việc update sẽ diễn ra bình thường. Nhưng nếu trả về false, tất cả method còn lại của updating cycle method sẽ không được gọi nữa, kể cả render và component sẽ không được update, shouldComponentUpdate tự động nhận vào 2 argument là: nextProps và nextState, nextProps và nextState là prop và state được truyền từ một component khác đến, hay chính là giá trị prop và state nếu component được update, shouldComponentUpdate sẽ kiểm tra 2 giá trị này với prop và state hiện tại của nó. Nếu khác nhau sẽ tiến hành update component, còn không thì dừng hẳn lại update component. Điều này rất quan trọng nếu bạn muốn tăng performance cho React app của bạn(good). Ví du:

var React = require('react');

var Example = React.createClass({
  getInitialState: function () {
    return { subtext: 'Put me in an <h2> please.' };
  },

  shouldComponentUpdate: function (nextProps, nextState) {
    if ((this.props.text == nextProps.text) && 
      (this.state.subtext == nextState.subtext)) {
      alert("Props and state haven't changed, so I'm not gonna update!");
      return false;
    } else {
      alert("Okay fine I will update.");
      return true;
    }
  },

  render: function () {
    return (
      <div>
        <h1>{this.props.text}</h1>
        <h2>{this.state.subtext}</h2>
      </div>
    );
  }
});

Method thứ 3 trong updating lifecycle method là componentWillUpdate. Nó được gọi giữa shouldComponentUpdate và render. Nó cũng nhận vào 2 argument và nextProps và nextState.

var React = require('react');

var Example = React.createClass({
  componentWillUpdate: function (nextProps, nextState) {
    alert('Component is about to update!  Any second now!');
  },

  render: function () {
    return <h1>Hello world</h1>;
  }
});

Có một điều chú ý ở đây là, bạn không thể gọi this.setState trong componentWillUpdate. Mục tiêu chính của componentWillUpdate là tương tác những thứ bên ngoài kiến trúc React. Nếu bạn cần set up một cái gì đó ngoài React, như check window size hay tương tác với một API thì componentWillUpdate là nơi thích hợp để thực hiện điều đó.

Tiếp theo là method render và cuối cùng trong updating lifecycle method là componentDidUpdate. Khi một component instance update, componentDidUpdate sẽ được gọi sau khi render HTML được loading xong.

var React = require('react');

var Example = React.createClass({
  componentDidUpdate: function (prevProps, prevState) {
    alert('Component is done rendering!');
  },

  render: function () {
    return <h1>Hello world</h1>;
  }
});

componentDidUpdate tự động được truyền vào 2 argument là prevProps và prevState. prevProps và prevState sẽ tham chiếu đến prop và state của component trước khi quá trình update component bắt đầu. Chúng ta có thể so sánh 2 argument này với giá trị hiện tại của prop và state. componentDidUpdate thường được sử dụng để tương tác với một số thứ bên ngoài vào môi trường React như là browser hay APIs. Nó tương tự như componentWillUpdate ngoại trừ việc nó được gọi sau method render.

Quá trình unmounting của component xảy ra khi component bị removed từ một DOM. Việc này có thể xảy ra khi một DOM được render mà không có component hoặc nếu user chuyển hướng đến một trang web khác hoặc khi trình duyệt được đóng. Chỉ có duy nhất một method trong quá trình này là: componentWillUnmount, componentWillUnmount sẽ được gọi trước khi một component bị remove khỏi một DOM. Nếu một component khởi tạo bất kì một method nào mà method đó yêu cầu phải clean up thì componentWillUnmount sẽ là nơi bạn nên đặt clean up.

var React = require('react');

var Example = React.createClass({
  componentWillUnmount: function () {
    alert('Goodbye world');
  },

  render: function () {
    return <h1>Hello world</h1>;
  }
});

Trên đây chúng ta đã lần lượt đi từng bước trong toàn bộ vòng đời của một component. Hy vọng giúp các bạn đang tìm hiểu về React có được cái nhìn toàn cảnh về cách component làm việc nói riêng và react làm việc nói chung. Thanks for read!

0