Bắt đầu và khái niệm cơ bản về React.js

React là gì?

React là một thư viện UI được phát triển tại Facebook để tạo điều kiện cho việc tạo ra các thành phần giao diện người dùng tương tác, trạng thái và có thể tái sử dụng. Nó được sử dụng tại Facebook và Instagram.com được viết hoàn toàn bằng React

Một trong những đặc điểm độc đáo là nó không chỉ được dùng để thực hiện trên phía client, mà nó cũng có thể được render ở phía server và chúng có thể hoạt động tương thích với nhau

Nó cũng sử dụng một khái niệm gọi là DOM ảo để lọc ra các nhánh con của node cần cập nhập dựa trên các thay đổi trạng thái. Nó có thể thực hiện các tương tác với DOM ít nhất để đảm bảo các thành phần luôn được cập nhập

DOM ảo hoạt động như thế nào?

Hãy tưởng tượng bạn có một object mà bạn đã mô hình hoá theo một người. Nó có tất cả các thuộc tính liên quan đến một người có thể có và phản chiếu các trạng thái hiện tại của một người. Về cơ bản đây là những gì React làm với DOM

Hãy tưởng tượng nếu bạn lấy object đó và tạo một vài thay đổi. Thêm ria mép, bắp tay và thay đổi đôi mắt. Trong React, khi chúng ta áp dụng những thay đổi này, hai việc xảy ra. Đầu tiên, React sẽ chạy một thuật toán “diffing” để xác định những gì đã thay đổi. Bước tiếp theo là reconciliation, nơi nó cập nhập DOM với kết quả của diff

Bắt đầu

Để bắt đầu với React, cài đặt công cụ React CLI (Tạo React App) và chạy câu lệnh để tạo một app mới:

# Install the CLI tool
npm install -g create-react-app

# Create an app
create-react-app my-app-name

# Install Dependencies
cd my-app-name
npm install

Cài đặt trang

Khi thiết lập trang của bạn, nếu bạn muốn bao gồm react.jsreact-dom.js, cũng như script biên dịch Babel. Sau đó bạn viết component của bạn trong script với kiểu đặt là text/babel

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>Hello World</title>
    <script src="https://unpkg.com/react@latest/dist/react.js"></script>
    <script src="https://unpkg.com/react-dom@latest/dist/react-dom.js"></script>
    <script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
  </head>
  <body>
    <div id="myDiv"></div>
    <script type="text/babel">

    <!-- React Code Goes Here -->

    </script>
  </body>
</html>

Trong React, các component được gắn vào một element, nên trong ví dụ này chúng ta sử dụng một div,  myDiv, nó là một vùng chứa chính.

Đây là cách dễ nhất để bắt đầu, thời gian thực sự dùng xây dựng cái gì đấy, nó có thể là ý tưởng tốt để sử dụng Browserify hoặc Webpack ( tạo một app sử dụng Webpack) để thiết lập các component của bạn trong file riêng biệt.

Cơ bản

Các khối xây dựng cơ bản của React được gọi là các components. Ví dụ như sau

<script type="text/jsx">
    /** @jsx React.DOM */
    React.render(
        <h1>Hello, world!</h1>,
        document.getElementById('myDiv')
    );
</script>

Nếu bạn chưa nhìn những thứ này bao giờ trước đây thì bạn sẽ tự hỏi đoạn code Javscript/HTML được đặt vào đây sẽ hoạt động như thế nào

JSX

Nó được gọi là JSX, và nó là một biến thể cú pháp XML Javascript. Điều này giúp bạn viết các thẻ HTML-ish trong Javascript của bạn. Bạn thực ra chỉ đang viết miêu tả các object dựa trên XML.

Đối với các thẻ HTML thông thường, thuộc tính class là className, và thuộc tính forhtmlFortrong JSX bởi vì đây là những từ dùng riêng cho Javascript. Bạn có thể xem thêm các khác biệt khác tại đây.

Giờ đây bạn không cần phải dùng JSX, đây là ví dụ cú pháp được trông ra sao mà không cần nó

/** @jsx React.DOM */
React.render(
  React.DOM.h1(null, 'Hello, world!'),
  document.getElementById('myDiv')
);

Bạn có thể đọc thêm các element được hỗ trợ ở đây nếu bạn thích

Trong đoạn code đầu tiên, bạn có để ý /** @jsx React.DOM */ở trên đầu không? Cái này là quan trọng, nó nói với React rằng chúng ta đang sử dụng JSX và đánh dấu cần được chuyển đổi, nên bạn cần bao gồm nó khi sử dụng cú pháp JSX.

Components

Khi sử dụng phương thức render ở trên, tham số đầu tiên là các thành phần chúng ta muốn render, tham số thứ hai là Node DOM mà ta muốn gắn vào. Chúng ta có thể dụng phương thức createClass để tạo các class Component tuỳ chỉnh.  Nó lấy một object xác định như một tham số, chúng ta sẽ tạo nó như bên dưới.

var MyComponent = React.createClass({
    render: function(){
        return (
            <h1>Hello, world!</h1>
        );
    }
});

Sau đó chúng ta có thể tạo một class, chúng ta có thể render nó trong document của chúng ta như sau

React.render(
    <MyComponent/>,
    document.getElementById('myDiv')
);

Props

Khi chúng ta sử dụng các Component được định nghĩa, chúng ta có thể thêm các thuộc tính được gọi là props. Những thuộc tính này có thể dùng trong Component như this.props và có thể được dùng trong phương thức render để biểu diễn dữ liệu thay đổi

var MyComponent = React.createClass({
    render: function(){
        return (
            <h1>Hello, {this.props.name}!</h1>
        );
    }
});

React.render(<MyComponent name="Handsome" />, document.getElementById('myDiv'));

Specs, lifecycle và state

Phương thức render là thông số cần thiết duy nhất cho việc tạo component, nhưng có một vài phương thức liffecycle và specs chúng ta có thể sử dụng rất hữu ích khi bạn thực sự muốn component của bạn làm bất cứ điều gì.

Các phương thức lifecycle

Đây là một vài phương thức lifecyle trong React bạn nên biết

  • componentWillMount: Được gọi một lần, trên cả client và server trước khi quá trình render diễn ra
  • componentDidMount: Được gọi một lần, chỉ trên client sau khi quá trình render diễn ra
  • shouldComponentUpdate: Được gọi trước khi quá trinh unmount(huỷ) component

Specs

  • getInitialState: Giá trị trả về là giá trị ban đầu cho state
  • getDefaultProps: Đặt các giá trị props dự phòng nếu props không được cung cấp.
  • mixins: Một mảng các object, thường được sử dụng để mở rộng chức năng của các Component hiện tại

Có nhiều phương thức lifecycle và specs khác nữa, bạn có thể đọc thêm ở đây

State

Tất cả các component đều có một object state và một object props. State được gán bằng cách sử dụng phương thức setState.  Gọi setState gây ra việc cập nhập UI và là không thể thiếu của tương tác React. Nếu bạn muốn gán cho một state ban đầu trước khi bất kỳ sự tương tác nào xảy ra chúng ta có thể sử dụng phương thức getInitialState. Bên dưới đây, chúng ta biết làm thế nào để gán cho state của component.

var MyComponent = React.createClass({
    getInitialState: function(){
        return {
            count: 5
        }
    },
    render: function(){
        return (
            <h1>{this.state.count}</h1>
        )
    }
});

Các Event

React cũng có hệ thống event tích hợp. Các event được đính kèm như các thuộc tính của các component và có thể  kích hoạt các phương thức. Chúng ta sẽ cho phép tăng dần số đếm mỗi khi có event click xảy ra như bên dưới đây.

/** @jsx React.DOM */

var Counter = React.createClass({
  incrementCount: function(){
    this.setState({
      count: this.state.count + 1
    });
  },
  getInitialState: function(){
     return {
       count: 0
     }
  },
  render: function(){
    return (
      <div class="my-component">
        <h1>Count: {this.state.count}</h1>
        <button type="button" onClick={this.incrementCount}>Increment</button>
      </div>
    );
  }
});

React.render(<Counter/>, document.getElementById('myDiv'));

Luồng dữ liệu một chiều

Trong React, luồng dữ liệu ứng dụng một chiều thông qua các object stateprops, trái ngược với ràng buộc 2 chiều của thư viện Angular. Điều này nghĩa là trong một Component đa thành phần, thông thường một component cha nên quản lý state và truyền nó xuống Component con thông qua props

State của bạn nên được cập nhập sử dụng phương thức setState để đảm bảo rằng việc làm mới UI  sẽ xảy ra, nếu cần thiết. Các giá trị kết quả nên được truyền xuống các component con sử dụng các thuộc tính mà có thể truy cập được ở thành phần con thông qua this.props

Xem ví dụ này để thấy khái niệm trên trong thực tế

/** @jsx React.DOM */

var FilteredList = React.createClass({
  filterList: function(event){
    var updatedList = this.state.initialItems;
    updatedList = updatedList.filter(function(item){
      return item.toLowerCase().search(
        event.target.value.toLowerCase()) !== -1;
    });
    this.setState({items: updatedList});
  },
  getInitialState: function(){
     return {
       initialItems: [
         "Apples",
         "Broccoli",
         "Chicken",
         "Duck",
         "Eggs",
         "Fish",
         "Granola",
         "Hash Browns"
       ],
       items: []
     }
  },
  componentWillMount: function(){
    this.setState({items: this.state.initialItems})
  },
  render: function(){
    return (
      <div className="filter-list">
        <input type="text" placeholder="Search" onChange={this.filterList}/>
      <List items={this.state.items}/>
      </div>
    );
  }
});

var List = React.createClass({
  render: function(){
    return (
      <ul>
      {
        this.props.items.map(function(item) {
          return <li key={item}>{item}</li>
        })
       }
      </ul>
    )  
  }
});

React.render(<FilteredList/>, document.getElementById('myDiv'));

 

You May Also Like

About the Author: Nguyen Dinh Thuc

Leave a Reply

Your email address will not be published.