React’s Five Fingers of Death

Đây là bài dịch, link gốc mời các bạn xem ở đây: https://medium.freecodecamp.com/the-5-things-you-need-to-know-to-understand-react-a1dbd5d114a3#.ti0nlz4t3

"Five Fingers of Death" của React. Làm chủ 5 khái niệm này, sau đó làm chủ React.

Cách đây vài năm, bạn của tôi Sean bắt đầu nói với tôi cách mà thư viện front-end được gọi là React này chiếm lấy web. Ban đầu tôi bác bỏ nó như một Framework khác. Nhưng sau đó tôi bắt đầu nghe về React nhiều hơn và nhiều hơn, đến mức mà tôi cảm thấy việc bỏ qua nó không còn là một lựa chọn nữa.

Có lẽ bạn cũng ở vào vị trí như tôi: nghe rất nhiều về React, nhưng thực sự ngồi xuống và học nó cảm giác như phải đi làm việc nhà vậy.

Tin vui là bạn có thể bỏ tất cả những gì bạn cần biết về React vào trong 5 khái niệm then chốt.

Điều này không có nghĩa là tôi có thể biến bạn thành master React ngay lập tức. Nhưng ít nhất bạn sẽ hiểu các khái niệm chính, nếu bạn quuyết định tìm hiểu về React.

Năm khái niệm đó là:

  1. Components
  2. JSX
  3. Prop & State
  4. Component API
  5. Component Types

Concept 1: React components hoạt động như thế nào ?

Điều đầu tiên chúng ta cần biết về React đó là tất cả đều xoay quanh components. React codebase của chúng ta, về cơ bẳn cũng chỉ là một tập hợp các components lớn gọi các components nhỏ hơn. Nhưng components là gì ? Một ví dụ hoàn hảo về component là <select> của HTML. Không chỉ có hình ảnh của riêng nó - nó cũng xử lý nhưng logic mở và đóng của chính nó. Bây giờ, hãy tưởng tượng chúng ta có thể xây dựng những thẻ select của mình. Đó chính xác là những gì React phép chúng ta làm. Một React Component là một object không chỉ xuất ra HTML như một template truyền thống mà còn bao gồm cả các mã cần thiết để kiểm soát nó. Trong thực tế, cách phổ biến nhất để viết một component là một lớp ES6 chứa phương thức render trả về React Element. (Có một cách bí mật nữa đó là sử dụng function, nhưng chúng ta sẽ đợi đén concept #5 để tìm hiểu về nó):

class MyComponent extends React.Component {
  render() {
    return <p>Hello World!<p>;
  }
}

Concept 2: JSX hoạt động thế nào

Như bạn thấy, components có chứa cả HTML và JavaScript trong cùng file. Vũ khí bí mật của React để đạt được sự kết hợp này là JSX (trong đó X là viết tắt của XML). Ban đầu, JSX có vẻ hơi bất tiện, nhưng bạn sẽ quen với nó nhanh thôi. Vâng, tôi biết. Chúng ta đều được dạy cách duy trì sự tách biệt manh mẽ giữa HTML và JavaScript. Nhưng nó chỉ ra rằng việc giãn các quy tắc này một chút có thể thực sự làm nên điều kì diệu cho năng suẩt front-end. Ví dụ, vì bây giờ bạn có toàn quyền sử dụng JS, dưới đây là cách mà bạn có thể hiển thị ngày bằng cách chèn một đoạn JS trong HTML:

class MyComponent extends React.Component {
  render() {
    return <p>Today is: {new Date()}</p>;
  }
}

Điều này cũng có nghĩa là chúng ta có thể sử dụng if hoặc loops của JS, chứ không phải một loại cú pháp của template nào đó.

class MyComponent extends React.Component {
  render() {
    return <p>Hello {this.props.someVar ?  'World' : 'Kitty'}</p>;
  }
}

Concept 3: Props và State hoạt động như thế nào ?

Có thể bạn đã tự hỏi biến this.props.someVar đến từ đâu. Nếu bạn đã từng viết HTML, có lẽ bạn đã quen với các thuộc tính HTML như href của thẻ <a>. Trong React, thuộc tính được gọi là props (viết tắt của properties). Các component giao tiếp với nhau thông qua Props.

class ParentComponent extends React.Component {
  render() {
    return <ChildComponent message="Hello World"/>;
  }
}
class ChildComponent extends React.Component {
  render() {
    return <p>And then I said,{this.props.message}</p>;
  }
}

Vì lí do này, luồng dữ liệu của React là một chiều (unidirectional): dữ liệu chỉ có thể đi từ các components cha đến components con, chứ không phải theo cách khác. Đôi khi, một component cần phản ứng lại với dữ liệu không đến từ component cha (như user input chẳng hạn). Và đây là nơi state được đưa vào. Một ẩn dụ tốt để hiểu sự khác biệt giữa props và state là Etch-A-Sketch. Không giống những thứ như màu máy và vị trí nút quay của Etch-A-Sketch (props), bản vẻ (state) không phải là thuộc tính của Etch-A-Sketch. Nó là kết quả tạm thời của user input. Lưu ý rằng, state của component cũng có thể truyền cho component con như một props. Bạn có thể nghĩ điều này như một con sông lớn đổ xuống, với router, data layer, và các components khác nhau, mỗi thành phần này thêm luồng dữ liệu của chúng để hình thành state của ứng dụng. Bên trong một component, state được quản lý bằng cách sử dụng function setState, thường được gọi trong một xử lí sự kiện:

class MyComponent extends React.Component {
  handleClick = (e) => {
    this.setState({clicked: true});
  }
  render() {
    return <a href="#" onClick={this.handleClick}>Click me</a>;
  }
}

Trong thực tế, phần lớn dữ liệu trong ứng dụng React sẽ là prop. Chỉ khi nào cần nhận user input thì chúng ta mới sử dụng state để xử lý thay đổi.

Concept 4: Component API hoạt động như thế nào ?

Chúng ta đã đề cập đến rendersetState, cả hai đều là một phần của một bộ các phương thức của Component API. Một thứ hữu ích khác là constructor, thứ mà ta có thể sử dụng để khởi tạo state và bind method. Ngoài 3 chức năng này, React cũng cung cấp một tập hợp các callbacks được kích hoạt tại các thời điểm khác nhau trong vòng đời của component (trước khi load, sau khi load, sau gỡ bỏ ...). Nếu phần này có vẻ ngắn, đó là vì học React thực sự là làm chủ các niệm lập trình và kiến trúc hơn là học một bộ phương thức API. Đây là những gì làm cho nó mới mẻ. Nhưng hãy ghi nhớ, chúng tồn tại, vì bạn sẽ cần đến chúng một lúc nào đấy.

Concept 5: Component types hoạt động như thế nào ?

Chúng ta đã thấy cách sử dụng classes để định nghĩa component:

class MyComponent extends React.Component {
  render() {
    return <p>Hello World!<p>;
  }
}

Và chúng ta cũng đã nói về những phương thức component được hỗ trợ bởi classes. Và bây giờ thì quên hết chúng đi! Ngày càng có nhiều người viết functional components Functional component là function nhận props object như đối số và trả về React element.

const myComponent = props => {
  return <p>Hello {props.name}! Today is {new Date()}.</p>
}

Hậu quả của việc sử dụng functional component là chúng ta mất quyền truy cập vào các function nêu ra ở mục #4. Nhưng thực tế chỉ ra rằng, điều đó vẫn ổn, vì phần lớn các component có lẽ sẽ không cần đến chúng. Một trong những function không thể sử dụng là setState, và điều này có nghĩa là functional components không thể có state. Vì lí do đó, chúng thường được gọi là stateless component. Vì các functional component yêu cầu ít boilerplate code hơn, nên có thể sử dụng bất cứ khi nào có thể. Vì kú do này, hầu hết ứng dụng React đều có kết hợp của cả 2 cú pháp. Lưu ý rằng có một cú pháp kế thừa thứ ba sử dụng function createClass. Nhưng nó đã quá cũ (18 tháng tại thời điểm viết bài)

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

Concept 6: Các vai trò của Component

Được rồi, tôi đã nói dối. Thực sự là có 6 điều, không phải 5. Nhưng mà không có bộ phim nào gọi là "Six Fingers Of Death" cả, Quay lại với chủ đề chính. Giờ đến các khái niệm kiến trúc nhàm chán mà tôi đã nói. Nếu không có điều gì có ý nghĩa ở đây, hãy trở lại khi bạn đã có cơ hội làm việc với React nhiều hơn. Sau khi sử dụng React một thời gian, mọi người bắt đầy thấy hai "mùi vị" xuất hiện trong component của họ. Một quan tâm tới UI logic như hiển thị hay ẩn điều gì đó. Và phần còn lại là về logic dữ liệu, chẳng hạn như tải dữ liệu từ máy chủ. Điều này dẫn đến sự khác biệt giữa containerpresentational componenents (đôi khi còn được gọi là smartdump components). Container nên xử lý dữ liệu không phải UI. Presentational thì ngược lại. Nói cách khác, trong ví dụ To-Do cổ điển, một component sẽ load dữ liệu và sau đó chuyển dữ liệu đó đến một component khác chịu trách nhiệm xuất ra HTML và xử lý các thay đổi state cục bộ. Điều này khá giống với view/controller pattern chúng ta đã quen thuộc ở back-end. Sự phân biệt container/presentational được phổ biến trong bài đăng của Dan Abramov (người tạo ra Redux), và tôi khuyến khích bạn nên đọc qua nó nêu muốn tìm hiểu sâu hơn.

Higher-Order Components

Trước khi chúng ta kết thúc, chúng ta nên nói một chút về một loại container component gọi là higher-order components (viết tắt là HoCs). HoC là một component có thể bao quanh component khác để gửi props đặc biệt cho component đó, và nó thường được tạo ra bằng cách sử dụng higher-order component factory function HoC là môt khái niệm mạnh mẽ. Với sự phổ biến của HoC, có vẻ như React có thể rời khỏi cú pháp ES6 class và hướng tới hướng tiếp cần thuần functional.

Kết

Chúng ta đã tìm hiểu được kha khá thứ. Tin hay không tùy bạn, nhưng chúng ta đã phủ được 90% kiên thức được sử dụng bởi React developer hằng ngày. Bất kể bị trừu tượng hay che giấu bởi pattern, mọi thứ trong React luôn có thể quy về functions và props. Một khi bạn thực sự hiểu được điều này, React sẽ không còn đáng sợ nữa.