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")
);