+3

React Without ES6

Chào các bạn mình quay trở với loạt bài ngâm cứu về ReactJs. Bài viết hôm nay mình giới thiệu các bạn sử dụng ReactJs khi không dùng ES6 như thế nào 😀. Thông thường, bạn sẽ định nghĩa một Component React là một lớp JavaScript đơn giản:

    class Greeting extends React.Component {
        render() {
            return <h1>Hello, {this.props.name}</h1>;
      }
    }

Nếu bạn chưa sử dụng ES6, bạn có thể sử dụng create-react-class mô-đun thay thế:

    var createReactClass = require('create-react-class');
    var Greeting = createReactClass({
      render: function() {
        return <h1>Hello, {this.props.name}</h1>;
      }
    });

API của các lớp ES6 tương tự như createReactClass() với một vài ngoại lệ.

1. Khai báo Props mặc định

Với các hàm và các lớp ES6 defaultProps được định nghĩa là một thuộc tính trên chính component đó:

    class Greeting extends React.Component {
      // ...
    }

    Greeting.defaultProps = {
      name: 'Mary'
    };

Với createReactClass(), bạn cần xác định getDefaultProps() là một hàm trên đối tượng đã truyền:

    var Greeting = createReactClass({
      getDefaultProps: function() {
        return {
          name: 'Mary'
        };
      },

      // ...

    });

2. Đặt trạng thái ban đầu

Trong các lớp ES6, bạn có thể xác định trạng thái ban đầu bằng cách gán this.state trong hàm tạo:

    class Counter extends React.Component {
      constructor(props) {
        super(props);
        this.state = {count: props.initialCount};
      }
      // ...
    }

Với createReactClass(), bạn phải cung cấp một phương thức getInitialState riêng trả về trạng thái ban đầu:

    var Counter = createReactClass({
      getInitialState: function() {
        return {count: this.props.initialCount};
      },
      // ...
    });

3. Autobinding

Trong các Component React được khai báo là các lớp ES6, các phương thức tuân theo cùng ngữ nghĩa như các lớp ES6 thông thường. Điều này có nghĩa là họ không tự động liên kết thisvới instance. Bạn sẽ phải sử dụng rõ ràng .bind(this)trong hàm tạo:

    class SayHello extends React.Component {
  constructor(props) {
    super(props);
    this.state = {message: 'Hello!'};
    // This line is important!
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
    alert(this.state.message);
  }

      render() {
        // Because `this.handleClick` is bound, we can use it as an event handler.
        return (
          <button onClick={this.handleClick}>
            Say hello
          </button>
        );
      }
    }

Với createReactClass(), điều này là không cần thiết bởi vì nó liên kết tất cả các phương thức:

    var SayHello = createReactClass({
      getInitialState: function() {
        return {message: 'Hello!'};
      },

      handleClick: function() {
        alert(this.state.message);
      },

      render: function() {
        return (
          <button onClick={this.handleClick}>
            Say hello
          </button>
        );
      }
    });

Điều này có nghĩa là việc viết các lớp ES6 đi kèm với một mã soạn sẵn hơn một chút cho các trình xử lý sự kiện, nhưng ưu điểm là hiệu năng tốt hơn một chút trong các ứng dụng lớn.

Nếu mã soạn sẵn quá hấp dẫn đối với bạn, bạn có thể kích hoạt đề xuất cú pháp Thuộc tính lớp thử nghiệm với Babel:

 class SayHello extends React.Component {
  constructor(props) {
    super(props);
    this.state = {message: 'Hello!'};
  }
  // WARNING: this syntax is experimental!
  // Using an arrow here binds the method:
  handleClick = () => {
    alert(this.state.message);
  }

  render() {
    return (
      <button onClick={this.handleClick}>
        Say hello
      </button>
    );
  }
}

Xin lưu ý rằng cú pháp ở trên là thử nghiệm và cú pháp có thể thay đổi hoặc đề xuất có thể không biến nó thành ngôn ngữ.

Nếu bạn muốn nó an toàn, bạn có một vài lựa chọn:

  • Các phương thức liên kết trong hàm tạo.
  • Sử dụng các chức năng mũi tên, ví dụ onClick={(e) => this.handleClick(e)}.
  • Tiếp tục sử dụng createReactClass.

4. Mixins

Đôi khi các component rất khác nhau có thể chia sẻ một số chức năng phổ biến. Chúng đôi khi được gọi là "mối quan tâm xuyên suốt" . createReactClass cho phép bạn sử dụng một mixins hệ thống kế thừa cho điều đó.

Một trường hợp sử dụng phổ biến là một component muốn tự cập nhật theo khoảng thời gian. Thật dễ dàng để sử dụng setInterval(), nhưng điều quan trọng là hủy bỏ khoảng thời gian của bạn khi bạn không cần nó nữa để tiết kiệm bộ nhớ. React cung cấp các phương thức vòng đời cho bạn biết khi nào một thành phần sắp được tạo hoặc hủy. Hãy tạo một mixinđơn giản sử dụng các phương thức này để cung cấp một chức năng setInterval() dễ dàng sẽ tự động được dọn sạch khi component của bạn bị phá hủy.

var SetIntervalMixin = {
  componentWillMount: function() {
    this.intervals = [];
  },
  setInterval: function() {
    this.intervals.push(setInterval.apply(null, arguments));
  },
  componentWillUnmount: function() {
    this.intervals.forEach(clearInterval);
  }
};

var createReactClass = require('create-react-class');

var TickTock = createReactClass({
  mixins: [SetIntervalMixin], // Use the mixin
  getInitialState: function() {
    return {seconds: 0};
  },
  componentDidMount: function() {
    this.setInterval(this.tick, 1000); // Call a method on the mixin
  },
  tick: function() {
    this.setState({seconds: this.state.seconds + 1});
  },
  render: function() {
    return (
      <p>
        React has been running for {this.state.seconds} seconds.
      </p>
    );
  }
});

ReactDOM.render(
  <TickTock />,
  document.getElementById('example')
);

Nếu một component đang sử dụng nhiều mixin và một số mixin xác định cùng một phương thức vòng đời (nghĩa là một số mixin muốn thực hiện một số dọn dẹp khi thành phần bị phá hủy), tất cả các phương thức vòng đời được đảm bảo được gọi. Các phương thức được xác định trên mixin chạy theo thứ tự mixin đã được liệt kê, theo sau là một lệnh gọi phương thức trên component.

5. Kết luận

Hi vọng bài viết này sẽ giúp các bạn hiểu thêm về ES6 trong ReactJs. Cảm ơn các bạn đã theo dõi. Trong bài viết có tham khảo tại https://reactjs.org/docs/react-without-es6.html.


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí