Học ReactJS Full Đầy Đủ Nhất

Bài 18: ReactJS - Bản rút gọn(Quick guide - P1)

Trong bài này, chúng ta sẽ đưa ra danh sách các bài tập , phương thức và công nghệ mà giúp ta giữ được tính nhất quán trong việc phát triển ứng dụng 
  • State - trạng thái nên được tránh càng nhiều càng tốt. Đó là điều tốt để để tập trung vào trạng thái và chuyển xuống cây component như props. Bất kí khi nào ta nhóm component mà cần giống dữ liệu, chúng ta nên đặt các phần tử xung quanh chúng và giữ trạng thái.Flux là cách tốt để xử lý trạng thái trong React apps
  • Proptypes - PropTypes nên luôn luôn được định nghĩa. Nó giúp cho việc theo dõi tất cả các props trong ứng dụng và cũng hữu ích đối với bất kì việc phát triển nào trong cùng project
  • Render - Hầu hết các ứng dụng logic nên  được xía bên trong hàm render. Ta nên cố gắng tối ưu hoá khối lượng công việc tính toán bên trong component lifecycle và di chuyển việc tính toán vào bên trong hàm render. Less state và props chúng ta sử dụng làm code sạch và đẹp . Ta nên luôn luôn làm cho trạng thái đơn giản nhất có thể. Nếu ta cần tính toán việc gì đó từ sate hay props, ta có thể làm nó bên trong hàm render
  • Composition - React team oigjw ý sử dụng  single responsibility principle(nguyên tắc phản hồi đơn). Điều này có nghĩa là 1 component chỉ nên phản hồi cho một function. Nếu nhiều components có nhiều hơn 1 hàm, ta nên refactor(cấu trúc lại) và tạo component mới cho mỗi hàm
  • Higher Order Components (HOC) - Các phiên bản React trước đây cung cấp các mixin để xử lý các chức năng có thể tái sử dụng. Vì mixin hiện không được dùng nữa, một trong những giải pháp là sử dụng HOC

I- ReactJS - Overview(Tổng quan) :

ReactJS là thư viện JavaScript được sử dụng dể xây dựng và tái sử dụng UI components. Theo thư việc chính thức của React, ta cũng xem định nghĩa sau :

"React is a library for building composable user interfaces. It encourages the creation of reusable UI components, which present data that changes over time. Lots of people use React as the V in MVC. React abstracts away the DOM from you, offering a simpler programming model and better performance. React can also render on the server using Node, and it can power native apps using React Native. React implements one-way reactive data flow, which reduces the boilerplate and is easier to reason about than traditional data binding."

1. Tính năng của React :
  • JSX - JSX là cú pháp mở rộng của JavaScript. Không cần thiết phải sử dụng JSX trong việc phát triển React, nhưng được khuyến nghị
  • Components - React được tạo ra từ các components. Bàn cần phải suy nghĩ về tất cả mọi thứ như một component. Điều này giúp cho bạn  trì được code khi nào việc với các dự án  scale lớn
  • Unidirectional data flow và Flux : React bổ sung luồng dữ liệu một chiều  giúp cho bạn suy luận dễ dàng về ứng dụng của bạn. Flux là công cụ hỗ trọ dữ cho dữ liệu chạy một chiều
  • License : React là một thư việc của Facebook Inc. Thư viện được cấp phép CC BY 4.0
2. ưu điểm của React :
  • Reactjs giúp việc viết các đoạn code JS dễ dàng hơn: Nó dung cú pháp đặc biệt là JSX (Javascript mở rộng) cho phép ta trộn giữa code HTML và Javascript. Ta có thể them vào các đoạn HTML vào trong hàm render mà không cần phải nối chuỗi. Đây là đặc tính thú vị của Reactjs. Nó sẽ chuyển đổi các đoạn HTML thành các hàm khởi tạo đối tượng HTML bằng bộ biến đổi JSX.
  • Nó có nhiều công cụ phát triển: Khi bạn bắt đầu Reactjs, đừng quên cài đặt ứng dụng mở rộng của Chrome dành cho Reactjs. Nó giúp bạn debug code dễ dàng hơn. Sau khi bạn cài đặt ứng dụng này, bạn sẽ có cái nhìn trực tiếp vào virtual DOM như thể bạn đang xem cây DOM thông thường.
  • Render tầng server: Một trong những vấn đề với các ứng dụng đơn trang là tối ưu SEO và thời gian tải trang. Nếu tất cả việc xây dựng và hiển thị trang đều thực hiện ở client, thì người dung sẽ phải chờ cho trang được khởi tạo và hiển thị lên. Điều này thực tế là chậm. Hoặc nếu giả sử người dung vô hiệu hóa Javascript thì sao? Reactjs là một thư viện component, nó có thể vừa render ở ngoài trình duyệt sử dụng DOM và cũng có thể render bằng các chuỗi HTML mà server trả về. Bạn có thể tham khảo cách render side servering tại đây. http://crypt.codemancers.com/posts/2016-09-16-react-server-side-rendering/
  • Làm việc với vấn đề test giao diện: Nó cực kì dễ để viết các test case giao diện vì virtual DOM được cài đặt hoàn toàn bằng JS.
  • Hiệu năng cao đối với các ứng dụng có dữ liệu thay đổi liên tục, dễ dàng cho bảo trì và sửa lỗi.
3. Nhược điểm của React :
Nhược điểm chính của reactjs đó là:
  • Reactjs chỉ phục vụ cho tầng View. React chỉ là View Library nó không phải là một MVC framework như những framework khác. Đây chỉ là thư viện của Facebook giúp render ra phần view. Vì thế React sẽ không có phần Model và Controller, mà phải kết hợp với các thư viện khác. React cũng sẽ không có 2-way binding hay là Ajax
  • Tích hợp Reactjs vào các framework MVC truyền thống yêu cầu cần phải cấu hình lại.
  • React khá nặng nếu so với các framework khác React có kích thước tương tương với Angular (Khoảng 35kb so với 39kb của Angular). Trong khi đó Angular là một framework hoàn chỉnh
  • Khó tiếp cận cho người mới học Web

II - Môi trường cài đặt :

a. Cài đặt Reactjs sử dụng Weback và Babel :
Webpack là một gói mô-đun (quản lý và tải các mô-đun độc lập). Nó nhận các mô-đun phụ thuộc và biên dịch chúng thành một gói (tệp) duy nhất. Bạn có thể sử dụng gói này trong khi phát triển ứng dụng bằng dòng lệnh hoặc bằng cách định cấu hình nó bằng tệp webpack.config.
Babel là một trình biên dịch và trình dịch JavaScript. Nó được sử dụng để chuyển đổi một mã nguồn khác.Khi sử dụng babel, bạn sẽ có thể sử dụng các tính năng ES6 mới trong code của mình, babel chuyển đổi nó thành ES5 cũ đơn giản có thể chạy trên tất cả các trình duyệt.
Bước 1 - Tạo thư mục gốc :
Tạo một thư mục có tên ReacApp trên màn hình nền để cài đặt tất cả các tệp cần thiết, sử dụng lệnh mkdir.
C:\Users\username\Desktop>mkdir reactApp
C:\Users\username\Desktop>cd reactApp
Để tạo bất kỳmô-đun nào, cần phải tạo tệp pack.json. Do đó, sau khi tạo thư mục, chúng ta cần tạo tệp pack.json. Để làm như vậy, bạn cần chạy lệnh npm init .
C:\Users\username\Desktop\reactApp>npm init
Lệnh này hỏi thông tin về mô-đun, chẳng hạn nhưpackagename, mô tả, tác giả, v.v. bạn có thể bỏ qua các tùy chọn này bằng cách enter và bỏ qua :v .
C:\Users\username\Desktop\reactApp>npm init -y
Wrote to C:\reactApp\package.json:
{
   "name": "reactApp",
   "version": "1.0.0",
   "description": "",
   "main": "index.js",
   "scripts": {
      "test": "echo \"Error: no test specified\" && exit 1"
   },
   "keywords": [],
   "author": "",
   "license": "ISC"
}
Bước 2 - cài đặt React và React Dom:
Vì nhiệm vụ chính trong bài hôm nàyi là cài đặt ReactJS và các gói dom của nó, sử dụng các lệnh install Reac và React-dom của npm tương ứng. Bạn có thể thêm các gói mình cài đặt, vào tệp pack.json bằng tùy chọn --save.
C:\Users\Tutorialspoint\Desktop\reactApp>npm install react --save
C:\Users\Tutorialspoint\Desktop\reactApp>npm install react-dom --save
Hoặc chỉ cần dùng 1 câu lệnh để cài đặt tất cả :
C:\Users\username\Desktop\reactApp>npm install react react-dom --save
Bước 3 : Cài đặt wepack 
Vì mình đang sử dụngwepack để cài đặt các gói webpack-dev-server và webpack-cli.
C:\Users\username\Desktop\reactApp>npm install webpack --save
C:\Users\username\Desktop\reactApp>npm install webpack-dev-server --save
C:\Users\username\Desktop\reactApp>npm install webpack-cli --save
Hoặc có thể dùng 1 dòng code để cài đặt như ở trên :
C:\Users\username\Desktop\reactApp>npm install babel-core babel-loader babel-preset-env 
   babel-preset-react html-webpack-plugin --save-dev
Bước 5 : Tạo file :
Để hoàn tất cài đặt, ta cần tạo một số tệp nhất định là index.html, App.js, main.js, webpack.config.js và, .babelrc. Bạn có thể tạo các tệp này theo cách thủ công hoặc, bằng cách sử dụng dấu nhắc lệnh.
C:\Users\username\Desktop\reactApp>type nul > index.html
C:\Users\username\Desktop\reactApp>type nul > App.js
C:\Users\username\Desktop\reactApp>type nul > main.js
C:\Users\username\Desktop\reactApp>type nul > webpack.config.js
C:\Users\username\Desktop\reactApp>type nul > .babelrc
Bước 6 : Cài đặt trình biên dịch, server và trình tải :
Mở tệpwebpack-config.js và thêm đoạn code sau .Mình đang đặt điểm nhập webpack thành main.js. Đầu ra là cổng 8001. Bạn có thể chọn bất kỳ cổng nào bạn muốn.webpack.config.js :
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
   entry: './main.js',
   output: {
      path: path.join(__dirname, '/bundle'),
      filename: 'index_bundle.js'
   },
   devServer: {
      inline: true,
      port: 8001
   },
   module: {
      rules: [
         {
            test: /\.jsx?$/,
            exclude: /node_modules/,
            loader: 'babel-loader',
            query: {
               presets: ['es2015', 'react']
            }
         }
      ]
   },
   plugins:[
      new HtmlWebpackPlugin({
         template: './index.html'
      })
   ]
}
Mở gói .json và xóa "test" "echo \" Lỗi: không có kiểm tra nào được chỉ định \ "&& thoát 1" bên trong đối tượng "scripts". Mình đang xóa dòng này vì mình sẽ không thực hiện thử nghiệm nào trong hướng dẫn này.  Bây giờ, bạn hãy thêm các lệnh để bắt đầu và chạy nó
"start": "webpack-dev-server --mode development --open --hot",
"build": "webpack --mode production"
Bước 7 : index.html
Đây là HTML thông thường.Mình đang đặt div id = "app" làm thành phần gốc cho ứng dụng và thêm tập lệnh index_bundle.js, đây là tệp ứng dụng đi kèm.
<!DOCTYPE html>
<html lang = "en">
   <head>
      <meta charset = "UTF-8">
      <title>React App</title>
   </head>
   <body>
      <div id = "app"></div>
      <script src = 'index_bundle.js'></script>
   </body>
</html>
Bước 8 : App.jsx và main.jsx 
Đây là thành phần React đầu tiên.Mình sẽ giải thích kĩ càng component của React trong một chương tiếp theo. Component này sẽ render  Hello World.
App.js :
import React, { Component } from 'react';
class App extends Component{
   render(){
      return(
         <div>
            <h1>Hello World</h1>
         </div>
      );
   }
}
export default App;
Ta cần phải import component này và render với App , kết quả sẽ hiển thị ở trình duyệt :
main.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App.js';

ReactDOM.render(<App />, document.getElementById('app'));
Lưu ý - Bất cứ khi nào bạn muốn sử dụng một cái gì đó, bạn cần nhập nó trước. Nếu bạn muốn component có thể sử dụng được trong các component của ứng dụng, bạn cần xuất nó sau khi tạo và nhập nó vào tệp mà bạn muốn sử dụng nó.Tạo một tệp có tên .babelrc và sao chép nội dung sau vào tệp .
{
   "presets":["env", "react"]
}
Bước 9 : Chạy server
Sau khi cài đặt xong mọi thử, ta có thể thử chạy server bằng dòng lệnh sau :
C:\Users\username\Desktop\reactApp>npm start
Trình duyệt hiển thị với cổng 8001 như dưới :

Bước 10 : Tạo Bundle 

Cuối cùng, để tạo gói tacần chạy lệnh build như sau-
C:\Users\Tutorialspoint\Desktop\reactApp>npm run build

2. Sử dụng câu lệnh create-react-app :

Thay vì sử dụng weback và babel ta có thể sử dụng câu lệnhcreate-react-appđể tạo
Bước 1 : Cài đặt create-react-app :
Duyệt qua các thư mục và cài đặt Ứng dụngCreate React Appnhư sau  :
C:\Users\Tutorialspoint>cd C:\Users\Tutorialspoint\Desktop\
C:\Users\Tutorialspoint\Desktop>npx create-react-app my-app
Như vậy ta đã tạo thành công thư mục có tên my-app và cài đặt tất cả các mục cần thiết ở trong folder
Bước 2 : Xóa tất cả các file nguồn
Duyệt qua thư mục src và xóa tất cả các file như đây :
C:\Users\Tutorialspoint\Desktop>cd my-app/src
C:\Users\Tutorialspoint\Desktop\my-app\src>del *
C:\Users\Tutorialspoint\Desktop\my-app\src\*, Are you sure (Y/N)? y
Bước 3 : Thêm file :
Thêm file index.css và index.jsvào thư mục src : 
C:\Users\Tutorialspoint\Desktop\my-app\src>type nul > index.css
C:\Users\Tutorialspoint\Desktop\my-app\src>type nul > index.js
Trong file index.js ta thêm các đoạn code sau :
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
Bước 4 : Chạy project 
Để chạy project ta sử dụng dòng lệnh sau :
npm start

III - ReactJS - JSX:

React sử dụng JSX để tạo khuôn mẫu thay vì JavaScript thông thường. Tuy nhiên, không cần thiết phải sử dụng , sau đây là một số ưu điểm của JSX.
  • Tốc độ nhanh hơn vì JSX thực hiện tối ưu hóa trong khi biên dịch mã sang JavaScript.
  • JSX thuộc loại type-safe và hầu hết các lỗi có thể mắc phải trong quá trình biên dịch.
  • Giúp bạn viết các template dễ dàng và nhanh hơn, nếu bạn đã quen với HTM
Cách sử dụng JSX
Jsx giống như 1 HTML thông thường trong hầu hết các trường hợp. Hãy xem đoạn code trong fileApp.jsx và trả về thẻ div
App.jsx 
import React from 'react';

class App extends React.Component {
   render() {
      return (
         <div>
            Hello World!!!
         </div>
      );
   }
}
export default App;
Mặc dù Jsx tương tự như HTML, nhưng có một số điều chúng ta cần lưu ý khi làm việc với JSX.
Nested Elements (phần tử lồng nhau)
Nếu bạn muốn trả về nhiều phần tử hơn,bạn cần bọc nó bằng một phần tử vùng chứa. Lưu ý cách mình  đang sử dụng thẻdiv dùng để bao bọc cho các phần tử h1, h2 và p.
import React from 'react';

class App extends React.Component {
   render() {
      return (
         <div>
            <h1>Header</h1>
            <h2>Content</h2>
            <p>This is the content!!!</p>
         </div>
      );
   }
}
export default App;
Các thuộc tính
Ta có thể sử dụng các thuộc tính tùy chỉnh của riêng mình ,ngoài các thuộc tính HTML thông thường. Khi ta muốn thêm thuộc tính tùy chỉnh, chúng ta cần sử dụng tiền tốdata-. Trong ví dụ sau, mình đã thêm data-myattribute làm thuộc tính của phần tử p
import React from 'react';

class App extends React.Component {
   render() {
      return (
         <div>
            <h1>Header</h1>
            <h2>Content</h2>
            <p data-myattribute = "somevalue">This is the content!!!</p>
         </div>
      );
   }
}
export default App;
Biểu thức JavaScript
Các biểu thức javaScript có thể được sử dụng bên trong JSX. Ta chỉ cần bọc nó bằng dấu ngoặc nhọn {}. Ví dụ sau sẽ cho ra kết quả là số 2.
import React from 'react';

class App extends React.Component {
   render() {
      return (
         <div>
            <h1>{1+1}</h1>
         </div>
      );
   }
}
export default App;
Ta không thể sử dụng các câu lệnh if else bên trong JSX, thay vào đó chúng ta có thể sử dụng các biểu thức điều kiện (bậc ba). Trong ví dụ sau, biến i bằng 1 nên trình duyệt sẽ hiển thị true, Nếu chúng ta thay đổi nó thành một số giá trị khác, nó sẽ hiển thị false.
import React from 'react';

class App extends React.Component {
   render() {
      var i = 1;
      return (
         <div>
            <h1>{i == 1 ? 'True!' : 'False'}</h1>
         </div>
      );
   }
}
export default App;
Styling(Kiểu) 
React khuyên bạn nên sử dụng các kiểu intline. Khi ta muốn thiết lập các kiểu inline, ta cần sử dụngcamelCaseReact cũng sẽ tự động thêm px sau giá trị số trên các phần tử cụ thể. Ví dụ sau đây cho thấy cách thêm myStyle inline vào thẻ h1.
import React from 'react';

class App extends React.Component {
   render() {
      var myStyle = {
         fontSize: 100,
         color: '#FF0000'
      }
      return (
         <div>
            <h1 style = {myStyle}>Header</h1>
         </div>
      );
   }
}
export default App;
Comments
Comment của chương trình là những lời diễn giải của người viết code , giúp cho người đọc, kiểm tra mã nguồn dễ hiểu hơn. Tất cả ngôn ngữ lập trình đều có cú pháp riêng để viết comment.Khi viếtcomments, ta cần đặt dấu ngoặc nhọn {} khi muốn viết comments trong phần con của thẻ. Một phương pháp hay là luôn sử dụng {} khi viết nhận xét, vì điều đó sẽ giúp ứng dụng nhất quán hơn.
import React from 'react';

class App extends React.Component {
   render() {
      return (
         <div>
            <h1>Header</h1>
            {//End of the line Comment...}
            {/*Multi line comment...*/}
         </div>
      );
   }
}
export default App;
Quy ước đặt tên
Các thẻ HTML luôn sử dụng tên thẻ viết thường, trong khi các thành phầnReact bắt đầu bằng chữ hoa.Lưu ý - Bạn nên sử dụng className và htmlFor làm tên thuộc tính XML thay vì class và for.Điều này được giải thích trên trang chính thức của React như sau-Vì JSX là JavaScript nên các định danh như class và for không được khuyến khích làm tên thuộc tính XML. Thay vào đó, các thành phần React DOM yêu cầu các tên thuộc tính DOM như className và htmlFor tương ứng.

IV- Components & State:

Bài 4: ReactJS - Components & State - ReactJS

Đăng bởi: Admin | Lượt xem: 44 | Chuyên mục: Javascript
Trong bài này,  ta sẽ tìm hiểu cách kết hợp các components để làm cho ứng dụng dễ bảo trì hơn. Cách tiếp cận này cho phép cập nhật và thay đổi các component mà không ảnh hưởng đến phần còn lại của trang.State biểu diễn trạng thái của component, state là private chỉ có thể thay đổi bên trong bản thân của chính component đó. Chúng ta có thể change states bằng cách gọi this.setState()

Stateless :

Mình sẽ minh họa lớp component trong App.jsx, lớp component này có thể được xem như là nơi chứa của Header và Content. Xem đoạn code dưới đây nhé :App.jsx
import React from 'react';

class App extends React.Component {
   render() {
      return (
         <div>
            <Header/>
            <Content/>
         </div>
      );
   }
}
class Header extends React.Component {
   render() {
      return (
         <div>
            <h1>Header</h1>
         </div>
      );
   }
}
class Content extends React.Component {
   render() {
      return (
         <div>
            <h2>Content</h2>
            <p>The content text!!!</p>
         </div>
      );
   }
}
export default App;
Để có thể chạy ứng dụng , ta cần phải import file main.js và gọi reactDOM.render()main.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App.jsx';

ReactDOM.render(<App />, document.getElementById('app'));
Và đây là kết quả hiển thị:

Stateful 

Trong ví dụ minh họa này, mình muốn đặt trạng thái cho lớp cha (App). Component Header chỉ được thêm vào giống như trong ví dụ trước vì nó không cần bất kỳ trạng thái nào. Thay vì thẻ Content, mình tạo các phần tử tablevà tbody, và tự động chèn TableRow cho mọi đối tượng từ mảng dữ liệu.Lưu ý rằng ở đây mình sử dụng cú pháp arrow syntax (=>) từ bảng EcmaScript 2015, trông code trở nên clean hơn. Điều này giúp ta sẽ tiết kiệm được dòng code , đặc biệt là khi tạo một danh sách với rất nhiều mục
App.jsx
import React from 'react';

class App extends React.Component {
   constructor() {
      super();
      this.state = {
         data: 
         [
            {
               "id":1,
               "name":"Foo",
               "age":"20"
            },
            {
               "id":2,
               "name":"Bar",
               "age":"30"
            },
            {
               "id":3,
               "name":"Baz",
               "age":"40"
            }
         ]
      }
   }
   render() {
      return (
         <div>
            <Header/>
            <table>
               <tbody>
                  {this.state.data.map((person, i) => <TableRow key = {i} 
                     data = {person} />)}
               </tbody>
            </table>
         </div>
      );
   }
}
class Header extends React.Component {
   render() {
      return (
         <div>
            <h1>Header</h1>
         </div>
      );
   }
}
class TableRow extends React.Component {
   render() {
      return (
         <tr>
            <td>{this.props.data.id}</td>
            <td>{this.props.data.name}</td>
            <td>{this.props.data.age}</td>
         </tr>
      );
   }
}
export default App;
main.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App.jsx';

ReactDOM.render(<App/>, document.getElementById('app'));
Lưu ý -  ở đây ta đang sử dụng hàm key = {i} bên trong map (). Điều này sẽ giúp React chỉ cập nhật các phần tử cần thiết thay vì hiển thị lại toàn bộ danh sách khi có điều gì đó thay đổi. Đó là một sự tăng hiệu suất rất lớn cho số lượng lớn hơn các phần tử được tạo động.

Ví dụ 1

class App extends React.Component {
  constructor(props) {
    super(props)

    this.state = {
      name: 'your name'
    }
  }

  onChange(e) {
    this.setState({name: e.target.value});
  }

  render() {
    return (
      <div>
        <input type='text' onChange={this.onChange.bind(this)} />
        <Notification title="hello">{this.state.name}</Notification>
      </div>
    );
  }
}
  • Ở đây chúng ta khởi tạo state với name: 'your name'
  • Hàm onChange được gọi mỗi khi giá trị input thay đổi và nó sẽ setState name bằng giá trị input
  • state.name được truyền vào component Notification thông qua props.children 
  •   Mỗi khi state.name thay đổi thì component Notification sẽ được render lại.   
Kết quả:

Ví dụ 2

App.jsx
import React from 'react';

class App extends React.Component {
   constructor(props) {
      super(props);
		
      this.state = {
         header: "Header from state...",
         content: "Content from state..."
      }
   }
   render() {
      return (
         <div>
            <h1>{this.state.header}</h1>
            <h2>{this.state.content}</h2>
         </div>
      );
   }
}
export default App;
main.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App.jsx';

ReactDOM.render(<App />, document.getElementById('app'));
Kết quả hiển thị như sau :