0x02 – Hooks


Preface

Hooks được ReactJS cung cấp từ phiên bản 1.18

Hooks sẽ được gắn vào components.

Hooks là gì ?

Hooks là hàm, được ReactJS cung cấp.

useState Hook

Quản lý state của dữ liệu, khi dữ liệu thay đổi (setState), re-render UI.

useState nhận một giá trị đầu vào (giá trị khởi tạo). Khi đó, useState sẽ lấy giá trị khởi tạo trong lần đầu tạo state.

Hooks useState sẽ trả về một mảng hai phần tử, đầu tiên là giá trị khởi tạo (state), thứ hai là hàm để thay đổi giá trị (setState)

import { useState } from "react"

function Component() {
    const [state, setState] = useState(initial_state);
    ...
}

Ứng dụng đếm số bắt đầu từ 1

import * as React from "react";
import ReactDOM from "react-dom";

function MyComponent() {
    // useState and set initial value
    const [counter, setCounter] = React.useState(1);
    
    const handleButtonClick = () => {
        setCounter(counter + 1);
    }
    
    return (
        <div>
            <h1> { counter } </h1>
            <button onClick={handleButtonClick}> Click To Increase </button>
        </div>
    )
}

ReactDOM.render (
    <React.StrictMode>
        <MyComponent />
    </React.StrictMode>,
    document.getElementById("root")
)

Dùng setState với callback

import * as React from "react";
import ReactDOM from "react-dom";

function MyComponent() {
    // useState and set initial value
    const [counter, setCounter] = React.useState(1);
    
    const handleButtonClick = () => {
        setCounter(prevState => {
            return prevState + 1;
        });
    }
    
    return (
        <div>
            <h1> { counter } </h1>
            <button onClick={handleButtonClick}> Click To Increase </button>
        </div>
    )
}

ReactDOM.render (
    <React.StrictMode>
        <MyComponent />
    </React.StrictMode>,
    document.getElementById("root")
)

useState với giá trị khởi tạo là một callback

import * as React from "react";
import ReactDOM from "react-dom";

function MyComponent() {
    // useState and set initial value by (imagine) fetching data from API
    const [counter, setCounter] = React.useState(() => {
        // imagine this task will take a lot of time.
        // by using this, this task will be executed
        // only one time. By that, make it more efficent.
        let a = 10;
        let b = 100;
        let result = a * b;
        
        return result;
    });
    
    const handleButtonClick = () => {
        setCounter(prevState => {
            return prevState + 1;
        });
    }
    
    return (
        <div>
            <h1> { counter } </h1>
            <button onClick={handleButtonClick}> Click To Increase </button>
        </div>
    );
}

ReactDOM.render (
    <React.StrictMode>
        <MyComponent />
    </React.StrictMode>,
    document.getElementById("root")
)

Note

Sau khi setState Component sẽ được re-render.

Initial state chỉ dùng cho lần khởi tạo đầu.

setState có thể dùng với callback.

useState có thể initial state với callback.

Two way binding

Print random number by user's input range

import * as React from "react";
import ReactDOM from "react-dom";

function App() {
    const [min, setMin] = React.useState();
    const [max, setMax] = React.useState();
    const [number, setNumber] = React.useState(NaN);

    const random_range = (min, max) => {
        setNumber(prevNumber => Math.floor(Math.random() * (max - min)) + min);
    };

    return (
        <React.Fragment>
            <div className="input-form">
                <label htmlFor="min">Min: </label>
                <input
                    id="min"
                    onChange={e => {
                        const value = Number(e.target.value);
                        setMin(value);
                    }}
                />
                <br />
                <br />
                <label htmlFor="max">Max: </label>
                <input
                    id="max"
                    onChange={e => {
                        const value = Number(e.target.value);
                        setMax(value + 1);
                    }}
                />
                <br />
                <br />
                <h1>Random number: {number}</h1>
                <br />
                <br />
                <button
                    onClick={() => {
                        random_range(min, max);
                    }}>
                    {isNaN(min) || isNaN(max) || max - 1 < min
                        ? "Invalid range"
                        : "Generate!"}
                </button>
            </div>
        </React.Fragment>
    );
}

ReactDOM.render(
    <React.StrictMode>
        <App />
    </React.StrictMode>,
    document.getElementById("root")
);

Two way binding with checkboxes and radios

CodeChoVui

CodeChoVui

Kỹ sư phần mềm, người đam mê hệ thống tối giản, web development và mã nguồn mở. Chia sẻ góc nhìn công nghệ và trải nghiệm lập trình thực chiến.

Theo dõi bản tin CodeChoVui

Nhận thông báo qua email mỗi khi có bài viết mới về lập trình, trải nghiệm phần mềm và công nghệ.

Gửi ý kiến thảo luận