Giới thiệu ReactJs

  1. **ReactJs là gì ?

**

ReactJS là một Javascript library được phát triển bởi Facebook đang ngày càng trở nên phổ biến hơn. ReactJS có thể hiểu như là một “cơ chế hiển thị giao diện dựa trên nền tảng Javascript – JavaScript-based UI rendering engine”.

React thường được so sánh với vai trò tương đương như các Javascript framework khác, nhưng việc so sánh giữa React và Angular thực sự không có ý nghĩa, bởi chúng sinh ra để đảm nhiệm những vai trò khác nhau. Angular là một framework hoàn chỉnh còn React thì không. Điều này lý giải tại sao thường gây ra một số hiểu lầm về React, bởi React thường được tích hợp trong một hệ sinh thái gồm các framwork hoàn chỉnh, nhưng nó chỉ phục vụ cho tầng View.

React cung cấp một ngôn ngữ tạo template và các function nhằm render ra các mã HTML. HTML là tất cả những gì mà React có thể output ra. Các đoạn mã HTML/Javascript được gọi là các “Component” nếu có khả năng lưu trữ các trạng thái (State) của chính nó trong bộ nhớ (ví dụ như tab nào được chọn trong một loạt các tab trên giao diện), nhưng cuối cùng chúng cũng chỉ sinh ra mã HTML mà thôi.

  1. **JSX

**

Nếu đã từng nghe nói về React, bạn cũng có thể đã nghe qua về JSX. Để thực sự cảm thấy hứng thú trong việc sử dụng JSX, bạn phải lưu ý đến hai điều sau:

  • Bạn phải thực sự hiểu JSX là gì, cũng như tất cả các sắc thái của nó.

  • Bạn phải có kinh nghiệm trong việc ra quyết định trong trường hợp nào thì nên sử dụng nó (React) và thực sự coi đó là điều cần thiết.

Vậy JSX là gì ? JSX = Javascript + XML. Nó là phần mở rộng của javascript nhưng có cú pháp viết như xml. JSX không phải một ngôn ngữ template, JSX chỉ đơn giản là một cú pháp thay thế JavaScript, mặc dù cú pháp đó là đặc trưng của React

Ví dụ về ReactJs và JSX

**JSX** **ReactJs**
`<div id="greeting-container" className="container">

<Greeting name="World"/>

div>
`
``` React.createElement("div", {

id: "greeting-container",

className: "container" },

React.createElement(Greeting, {name: "World"})

)
```
Cú pháp của JSX ngắn gọn, đơn giản, giống như code HTML. JSX hoàn toàn không bắt buộc, nhưng lại thực sự hữu ích vì hai lý do:
  • Nó cung cấp các shorthand hữu ích cho một số React boilerplate mà bắt buộc phải sử dụng dù muốn hay không

  • JSX làm javascript markup trông giống như HTML markup

Handlebars, Django templates và rất nhiều template languages khác cho phép thay thế giữa các plain text với một số template chuyên dùng. Template language hiếm khi có khả năng diễn đạt như của host language (ngôn ngữ lập trình chính thống: PHP, Python, Javascript…). JSX chỉ convert các đánh dấu XML thành code JavaScript. Nó tương tự như là bạn đang gõ code Javascript vậy.

Điều này rất tuyệt vì có thể sử dụng tối đa sức mạnh của JavaScript và tất cả mọi thứ bạn đã học về nó như các biểu thức, cấu trúc hàm, hay bất kỳ các tính năng nào khác trong views của bạn. Bạn không cần viết các helpers (hàm trợ giúp chuyên dùng) đặc trưng cho template language của mình mà chỉ cần sử dụng Javascript

**Data flow trong ReactJS
**

Ta sẽ sử dụng ví dụ được đưa trên trang chủ của ReactJS để minh họa

Khác với các Framework khác như AngularJS hay EmberJS, ReactJS không có những module chuyên dụng để xử lý data. Do đó nhiều người tham chiếu ReactJS như phần View của một MVC framework, tuy nhiên thay vì sử dụng phần view thuần HTML, ReactJS chia nhỏ view thành các component nhỏ có mỗi quan hệ chặt chẽ với nhau


  1. Thành phần cơ bản của ReactJS

ReactJS không có những module chuyên dụng để xử lý data. Do đó có thể tham chiếu ReactJS như phần View của một MVC. Tuy nhiên thay vì sử dụng phần view thuần HTML, ReactJS chia nhỏ view thành các component nhỏ có mối quan hệ chặc chẽ với nhau.

Theo ví dụ, ta có thể chia nhỏ như sau:


├── FilterableProductTable
│   ├── SearchBar
│   └── ProductTable
│       ├── ProductCategoryRow
│       └── ProductRow

Luồng truyền dữ liệu trong ReactJS là luồng dữ liệu một chiều từ cha xuống con thông quả props và state

  1. Props và state

Props và state là hai tham số cơ bản của ReactJS đều được sử dụng để truyền tải dữ liệu. Điểm khác biệt cơ bản nhất của hai tham số này là:

  • Props: Đây là tham số mà bản thân component không thể tự sinh ra, được truyền từ bên ngoài vào. Điểm đặc biệt là props không thể thay đổi được trong quá trình truyền tải dữ liệu

  • State: Tham số này được sinh ra nộ tại bên trong component, đặc trung cho component đó. Có thể thay đổi được giá trị

Tuy nhiên, nếu để sử dụng truyền tải dữ liệu xuống các component lớp dưới thì props và state không có sự khác biệt

`var FilterableProductTable = React.createClass({ getInitialState: function() { return { filterText: '', inStockOnly: false }; },`render: **function**() { **return **( <**div**> <**SearchBar filterText=**{**this**.***state***.**filterText**} **inStockOnly=**{**this**.***state***.**inStockOnly**} /> <**ProductTable products=**{**this**.**props**.products} **filterText=**{**this**.***state***.**filterText**} **inStockOnly=**{**this**.***state***.**inStockOnly**} /> **div**> ); } });

React.render(<FilterableProductTable products={PRODUCTS} />,
document.getElementById(‘products’));

Trên đây là đoạn code dùng để khởi tạo cho khung search với tên component là FilterableProductTable. Ở component này:
  • props: chỉ có products được truyền từ bên ngoài vào

  • state: bao gồm filterTextinStockOnly, được khởi tạo bởi getInitialState

Và ta có thể thấy rằng cả cả stateprops đều được sử dụng để truyền tham số xuống các component con là SearchBarProductTable. Và cứ liên tiếp tuần tự truyền như vậy, dữ liệu sẽ được truyền tải xuống tới component ở level thấp nhất là ProductRowProductCategoryRow


  1. Event handling

Ở trong form search này, chúng ta có hai thành phần thay đổi động theo input đầu vào là text box mang filterText và chekcbox để kiểm tra inStockOnly. Khi thông tin input thay đổi, chúng ta sẽ hiển thị product dựa trên thông tin đó. Event hanlding của ReactJS phải tuân theo cấu trúc dữ liệu một chiều từ cha xuống con. Do đó, việc các thành phần trong SearchBar tương tác trực tiếp với ProductTable hay là parent element là filterableProductTable là điều không thể vì nó sẽ đi ngược lại với one-way data flow.

Để có thể thực hiện điều này trong ReactJS, chúng ta phải thay đổi state của component gốc chính là filterableProductTable

`var SearchBar = React.createClass({ handleChange: function() { this.props.onUserInput( this.refs.filterTextInput.getDOMNode().value, this.refs.inStockOnlyInput.getDOMNode().checked ); }, render: function() { return ( <form><input type="text" placeholder="Search..." value={this.props.filterText}ref="filterTextInput" onChange={this.handleChange} /><p><input type="checkbox" checked={this.props.inStockOnly}ref="inStockOnlyInput" onChange={this.handleChange} /> {' '} Only show products in stock p>form> ); } }); var FilterableProductTable = React.createClass({ getInitialState: function() { return { filterText: '', inStockOnly: false }; },`handleUserInput: **function**(filterText, inStockOnly) { **this**.setState({ **filterText**: filterText, **inStockOnly**: inStockOnly }); },

render: function() {
**return **(
<div>
<SearchBar
filterText=
{this.state.filterText}
inStockOnly=
{this.state.inStockOnly}
onUserInput=
{this.handleUserInput}
/>

<ProductTable
products=
{this.props.products}
filterText=
{this.state.filterText}
inStockOnly=
{this.state.inStockOnly}
/>

</div>
);
}
});

Điều đặc biệt ở đây là chúng ta biến hàm setState() của element gốc thành props của SearchBar và từ SearchBar chúng ta có thể thay đổi trực tiếp state của FilterableProductTable và sẽ tự động thay đổi tên product hiển thị. Việc thay đổi này tuy có phần hơi phức tạp so với các phương pháp ở trên nhưng có thể mang lại một số lợi ích như:
  • Đảm bảo sự xuyên suốt từ trên xuống dưới
  • Hạn chế thay đổi trực tiếp trên DOM
  • Quản lý các event bên trong từng component
  • Có thể sử dụng lại trong tương lai (reuseable)
  1. **Kêt luận

**

Việc ReactJS sử dụng one-way data flow có thể gây ra một chút khó khăn cho những người muốn tìm hiểu và ứng dụng vào trong các dự án. Tuy nhiên, cơ chế này sẽ phát huy được ưu điểm của mình khi cấu trúc cũng như chức năng của view trở nên phức tạp thì ReactJS sẽ phát huy được vai trò của mình.