[React.js trong thực tiễn] Part1 : Hiểu khái niệm và đặc điểm của React

https://reactjs.org/

Thông tin series

  • [React.js trong thực tiễn] Part1. Hiểu khái niệm
  • [React.js trong thực tiễn] Part2. Bắt đầu một project
  • [React.js trong thực tiễn] Part3. Tạo list
  • [React.js trong thực tiễn] Part4. Biểu hiện Filter, sort
  • [React.js trong thực tiễn] Part5. Cho vào giỏ

Part này gồm những lý thuyết cơ bản cho những người lần đầu nhập môn React. Nếu bạn muốn thực hành làm bài luôn, tôi khuyên bạn nên bắt đầu từ [React.js trong thực tiễn] Part2. Bắt đầu một project.


Tại sao Facebook lại tạo React?

React là một library Front-end được cung cấp bởi Facebook.

Ngay cả trước khi Facebook tạo React, đã có rất nhiều framework tồn tại như AngularJS, Backbone.js, Knockout.js, Ember.js

Các framework trên cấu tạo hóa application bằng các pattern như MVC pattern hoặc MVVM (View Model),v...v...

Model View – ViewModel pattern (https://docs.microsoft.com/en-gb/xamarin/xamarin-forms/enterprise-application-patterns/mvvm)

Tức là, khi một event xảy ra, Model sẽ xử lý data và thay đổi View phụ trách màn hình dựa trên thông tin đó. Quá trình này nhìn thì có vẻ đơn giản, nhưng nếu quy mô application lớn thì sẽ khá phức tạp và tính năng cũng bị giảm sút.

Ý tưởng mà team lập trình facebook nghĩ tới ở đây không phải là lo lắng về những gì thay đổi khi data thay đổi, mà là thay đổi View với tốc độ nhanh hơn bằng cách "bỏ View cũ và sử dụng Virtual DOM rồi rendering mới lại từ đầu".


Ưu điểm của React

  • Tốc độ rất nhanh do sử dụng Virtual DOM.
  • Chỉ cần biết khái niệm đơn giản của Catchphrase, JavaScript và React được Facebook sử dụng khi công bố về React, ta có thể lập trình tất cả Web và App.
  • React thân thiện với JavaScript và là một công cụ tập trung vào việc quản lý tính bất biến.
  • Đã và đang được nhiều công ty sử dụng (Netflix, Airbnb, nhiều công ty HQ đa dạng) nên có nhiều library khác nhau tồn tại, và có nhiều câu hỏi và câu trả lời sôi nổi.

Đặc điểm của React

1. Cấu trúc Component

Với React, tất cả mọi thứ đều là Component. Component được tạo từ các đơn vị nhỏ giống như các khối lego, cho phép bạn lập trình như kiểu lắp ráp, vì vậy ta có được những lợi thế như đóng gói (encapsulation), mở rộng, kết hợp, tái sử dụng, v...v...

2. Luồng data một chiều

Trong React, bạn có thể chuyển data giữa Component bố mẹ và Component con, nhưng khi chuyển data, chỉ có thể chuyển data từ bố mẹ sang con.

3. ECMAScript 6

Lập trình React sử dụng ngôn ngữ ES6.

  • let

    Keyword có thể thay thế var hiện có. Các var hiện có thường làm rối loạn việc lập trình và giảm tính dễ đọc do lược bỏ câu khai báo, khai báo tên biến trùng lặp, thiết lập scope trong khối hàm số (function block), hoisting hàm số,... vì thế trong ES6 đang tránh sử dụng các var.

    Thiết đặt scope var trong block không phải hàm số

    var a = 100;
    if(a > 0){
        var a = 200;
        console.log(a); // 200 outputs
    }
    console.log(a); // 200 outputs
    

    Trong trường hợp ví dụ trên đổi thành let ⇒ có thể thiết đặt scope trong block ngoài hàm số.

    let a = 100;
    if(a > 0){
        let a = 200;
        console.log(a); // 200 outputs
    }
    console.log(a); // 100 outputs
    
  • const

    Là biến số không thể thay đổi, được sử dụng khi không cần gán lại giá trị. Khác với biến số, khi khai báo bắt buộc phải gán lại một giá trị ban đầu, và phạm vi scope là block level giống với let.

    const MY_NAME; // SyntaxError occurs because initial value is not assigned
    const MY_NAME = 'Kim';
    MY_NAME = 'Lee'; // TypeError when trying to change the value
    
  • Arrow function

    Cú pháp biểu thị hàm dùng mũi tên => để rút ngắn cú pháp.

    // Existing function syntax
    var add = function(a, b){
        return a + b;
    };
    // Arrow function syntax
    let add = (a, b) => {
        return a + b;
    }
    

    Có thể dùng biểu thức rút gọn cú pháp block {} nhưng trong trường hợp này sẽ không thể sử dụng return.

    // Using block syntax
    let add = (a, b) => {
        console.log(a + b);
    }
    // Omit block syntax
    let add = (a, b) => console.log(a + b);
    

    Nếu chỉ một tham số duy nhất được thông qua, có thể lược bỏ dấu ngoặc {}

    // Using parentheses
    let print = (message) => document.write(message);
    // Omit parentheses
    let print = message => document.write(message);
    
  • Spread operator

    Có thể sao chép tất cả giá trị của một đối tượng (object) hoặc một mảng (array) bằng toán tử (operator) sử dụng ...

    let a = [1,2,3]
    let b = a
    b.push(4);
    console.log(a) //[1,2,3,4]
    console.log(b) //[1,2,3,4]
    

    Như trong ví dụ trên, cú pháp được sử dụng để ngăn resource thay thế tất cả data trong một mảng là spread operator, và có liên quan đến tính bất biến của data.

    let a = [1,2,3]
    let b = [...a, 4]
    console.log(a) //[1,2,3]
    console.log(b) //[1,2,3,4]
    
  • Class

    Sử dụng class khiến ta không dần dùng Prototype mà vẫn có thể sử dụng kế thừa một cách đơn giản.

    // Declare class name after class keyword and write syntax inside block
    class Display {
    }
    const display = new Display();
    
  • Kế thừa

    Trong ES6, sử dụng keyword extends khiến bạn có thể thực hiện kế thừa dễ dàng hơn, và theo như nghĩa đen là truyền các thuộc tính hoặc chức năng của class bố mẹ (cấp trên) cho con.

    class Display{
        constructor(x, y){
            this.x = x;
            this.y = y;
        }
    }
    /* 
    Extend the declared Display class after the React class declaration
            Display class is inherited.
    */
    class React extends Display{
        constructor(x, y, width, height){
    /*
    As a constructor of the parent class, super is called to force the parent class to be initialized when the constructor is called from the child class.
    */
            super(x, y);  
            this.width = width;
            this.height = height;
        }
    }
    

Các khái niệm cần biết

1. Cú pháp JSX

React sử dụng cú pháp JSX - được tạo trên Facebook, nhìn giống và sử dụng tương tự như HTML, nhưng nó là một cú pháp hoàn toàn khác.

Trong JSX có một số quy tắc bắt buộc phải tuân theo.

1.1. Tag phải được đóng lại

import React, { Component } from 'react';

class App extends Component {
    render() {
        return (
            <div>
                <p>Hello world // Error occurred
                <p>Hello world</p> // In normal operation
                <input type='text' > Error occurred
                <input type='text' /> // In normal operation
            </div>
        );
    }
}

export default App;

1.2. Element bao bọc

Hai element trở lên bắt buộc phải được bao lại bằng một element.

<Trường hợp giải quyết bằng div>

import React, { Component } from ‘react’;

class App extends Component {
    render() {
        return (
            <div>
                <p> Hello world</p>
                <p> Have a Nice day :)</p>
            <div>
        );
    }
}

export default App;

<Trường hợp giải quyết bằng Fragment>

// When importing React, the Fragment must be loaded along with the Component.
import React, { Component, Fragment } from ‘react’;

class App extends Component {
    render() {
        return (
            <Fragment>
                <p> Hello world</p>
                <p> Have a Nice day :)</p>
            </Fragment>
        );
    }
}

export default App;

1.3. Sử dụng giá trị JavaScript trong JSX

import React, { Component } from 'react';

class App extends Component {
    render() {
        let name = 'react';
        return (
            <div>
                <p>Hi {name}!</p>
            </div>
        );
    }
}

export default App;

1.4. Viết CSS: inline style

React được viết bằng JavaScript, vì vậy như dưới đây, giá trị thuộc tính style phải được gán một JavaScript object chứ không phải một chuỗi thông thường.
Và tương tự với font-size, tên thuộc tính có dấu gạch ngang (-) ở giữa nên được thay đổi Camel case như fontSize. (Cách này không được recommend do vấn đề sửa chữa, bảo trì hoặc tính năng.)

import React, { Component } from 'react';

class App extends Component {
    render() {
        const styles = {
            backgroundColor: 'black',
            padding: '16px',
            color: 'white',
            fontSize: '12px'
        };
        
        return (
            <div style={styles}>
                Hello World
            </div>
        );
    }
}

export default App;

1.5. Viết CSS: Gọi file bên ngoài

Định nghĩa style trong file riêng và import file css được định nghĩa trong file React Component.

import './App.css' // Loading

1.6. class trong html là className

return (
    <div className="App">
        Hello World
    </div>
);

React DOM sử dụng camelCase làm quy ước đặt tên thay vì tên attribute HTML. Ví dụ, trong JSX, tabindex được viết thành tabIndex.
class attribute là một từ dành riêng (reserved word) trong JavaScript, được viết dưới dạng className.

2. Props và State

2.1. Props

Thuộc tính mà Component con kế thừa từ Component bố mẹ, nghĩa là sử dụng Props để Component bố mẹ truyền data đến Component con.

Props nhận được từ bố mẹ không thể sửa đổi trên con vì chúng được quy định buộc phải giữ luồng data một chiều.

src/App.js

Định nghĩa các thuộc tính mà App.js sẽ gửi cho Component con là Hello.

import React, { Component } from 'react';
import Hello from './hello.js';

class App extends Component {
    render() {
        return (
            <div className="App">
                <Hello text="React"/> //Justice
            </div>
        );
    }
}

export default App;
src/hello.js

Trong hello.js gọi props nhận được từ Component bố mẹ.

class Hello extends Component {
    render() {
        return (
            <div>
                <p>
                Hello {this.props.text} // Defined props call
                </p>
            </div>
        );
    }
}

2.2. State

State quản lý data biến động linh hoạt trong Component, và luôn phải đặt giá trị mặc định trước thì mới có thể sử dụng.

Hãy xem một ví dụ Counter trong đó số tăng lên bằng button click..

src/App.js
import React, { Component } from 'react';
import './App.css';
import Counter from './Counter.js'// Call component to display counter

class App extends Component {
    constructor(props) {
        super(props);
        this.state = {
            number: 0
        };
    }

//When the function is executed, the value of number increases by 1
    handleIncrease = () => {
        const { number } = this.state;\

//this.setState is a function used when changing the value of state
        this.setState({
            number: number + 1
        });
    }

    render() {
        return (
            <div className="App">
                <header className="App-header">
                    <img src={logo} className="App-logo" alt="logo" />
                    <Counter 
                       handleIncrease={this.handleIncrease}
                       number={this.state.number}
                    />
                </header>
            </div>
        );
    }
}
export default App;
src/Counter.js
import React, { Component } from 'react';

//Create Counter component and inherit Component
class Counter extends Component {
    render() {
        return (
            <div>
                <h1>Counter</h1>
                <div>value: {this.props.number}</div>
                <button onClick={this.props.handleIncrease}>+</button>
            </div>
        );
    }
}

export default Counter;

Khi thay đổi giá trị trong state, sử dụng phương thức (method) this.setState()

Thứ tự hoạt động
  1. Click button ở conuter.js và chạy this.props.handleIncrese
  2. app.js đã nhận event thực hiện hàm handleIncrese đã được khai báo và thay đổi giá trị number được khai báo trong state
  3. Thay đổi giá trị props chuyển tới conuter.js bằng thay đổi state trong app.js
  4. Sau khi nhận giá trị props được conuter.js thay đổi, hiển thị màn hình đã thay đổi.

Life Cycle (Vòng đời)

Lifecycle là một chuỗi quá trình trong React từ khi Component được hình thành, update, rồi huỷ.

Nếu người sử dụng muốn thêm tính năng tại một thời điểm cụ thể khi chạy React, họ có thể thêm tính năng bằng cách sử dụng LifeCycle API

Có thể được chia thành ba giai đoạn lớn [Mount - Update - Unmount]

3.1. Khi tạo Component (Mount)

constructor() => componentWillMount() => render() => componentDidMount()
  • constructor() : Là method người tạo, chỉ thực thi một lần khi Component được tạo, và chỉ có thể thiết lập state trong method này.
  • componentWillMount() : Là method được gọi ngay trước khi thêm React element vào DOM node thực tế. Vì DOM vẫn chưa được hình thành nên không thể thao tác DOM, và là trước khi render được gọi nên dù có sử dụng setState cũng sẽ không gọi được render.
  • render() : Chịu trách nhiệm rendering Component.
  • componentDidMount() : là method được gọi sau khi Component được tạo và gọi render.

3.2. Khi thay đổi Component (Update)

componentWillReceiveProps() => shouldComponentUpdate() => componentWillUpdate() => render() => componentDidupdate()
  • componentWillReceiveProps() : là method được gọi sau khi hình thành Component và hoàn thành rendering đầu tiên. Có ích khi cần nhận props và thay đổi state.
  • shouldComponentUpdate() : là method được gọi trước khi thay đổi Component. Khi props hoặc state được thay đổi, giá trị return sẽ quyết định có rendering lại hay không.
  • componentWillUpdate() : là method được gọi trước khi thay đổi Component sau khi gọi shouldComponentUpdate. Nó nhận các giá trị thay đổi ngay trước khi props hoặc state mới được phản ánh.

3.3. Khi xoá Component (Unmount)

componentWillUnmount()
  • componentWillUnmount() : là method thực thi khi Component bị huỷ (sau khi bị xoá khỏi DOM). Có ích cho việc xoá bỏ khi đang sử dụng timer hoặc API không đồng bộ bên trong Component.

Trong code thực tế, ta tập trung quản lý 6 loại API là constructor, render, componentDidMount, shouldComponentUpdate, componentDidUpdate, componentWillUnmount, và nếu như không hiểu ngay lập tức thì cũng không sao.


Vừa rồi ta đã hiểu được lý do tại sao dùng React và khái niệm cơ bản của nó.

Trong part tiếp theo sẽ là những nội dung luyện tập để bắt đầu việc setting môi trường lập trình.


URL tham khảo

  • https://ko.reactjs.org/tutorial/tutorial.html
  • https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference
  • https://opentutorials.org/course/697/3828
  • https://academy.nomadcoders.co/p/reactjs-fundamentals
  • https://velog.io/tags/react
  • https://react-anyone.vlpt.us/

Thông tin series


🔍 Chúng tôi đang tìm kiếm FE Developer tài năng đồng hành cùng với Hivelab.

Comments

Popular posts from this blog

[React.js trong thực tiễn] Part3 : Tạo list gọi data sử dụng axios

[Activity] Một ngày tới thăm công ty mẹ Hivelab

[Activity] Hành trình du lịch Hàn Quốc của nhân viên Hivelab Vina