Import useState

Để sử dụng hook useState, trước tiên ta cần import nó vào Function Component.

import { useState } from "react";

Đây là cấu trúc destructuring trong ES6 để import useState prop trong react object.

Khởi tạo useState

Chúng ta khởi tạo hook useState bên trong Function Component.
useState chấp nhật state ban đầu và trả về hai giá trị:

  • State hiện tại
  • Hàm cập nhật state
import { useState } from "react";

function FavoriteColor() {
  const [color, setColor] = useState("");
}

Lưu ý chúng ta đang destructure giá trị trả về từ useState:

  • Giá trị thứ nhất, color, là state hiện tại
  • Giá trị thứ hai, setColor, là hàm dùng để cập nhật state
    Sau cùng, chúng ta đặt trạng thái ban đầu là một chuỗi rỗng: useState("")

Đọc state

Chúng ta có thể thêm state vào bất cứ đâu trong component.
Ví dụ:

import { useState } from "react";
import ReactDOM from "react-dom/client";

function FavoriteColor() {
  const [color, setColor] = useState("red");

  return <h1>My favorite color is {color}!</h1>
}

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<FavoriteColor />);

Cập nhật state

Để cập nhật state, chúng ta sử dụng hàm cập nhật state. Chúng ta không nên cập nhật trạng thái trực tiếp. Ví dụ như color = 'red' là không đúng.

import { useState } from "react";
import ReactDOM from "react-dom/client";

function FavoriteColor() {
  const [color, setColor] = useState("red");

  return (
    <>
      <h1>My favorite color is {color}!</h1>
      <button
        type="button"
        onClick={() => setColor("blue")}
      >Blue</button>
    </>
  )
}

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<FavoriteColor />);

State có thể lưu trữ gì

Hook useState có thể được dùng để theo dõi chuỗi, số, boolean, mảng, object và kết hợp của những kiểu dữ liệu này.
Chúng ta có thể tạo nhiều hook useState để theo dõi nhiều giá trị riêng:

import { useState } from "react";
import ReactDOM from "react-dom/client";

function Car() {
  const [brand, setBrand] = useState("Ford");
  const [model, setModel] = useState("Mustang");
  const [year, setYear] = useState("1964");
  const [color, setColor] = useState("red");

  return (
    <>
      <h1>My {brand}</h1>
      <p>
        It is a {color} {model} from {year}.
      </p>
    </>
  )
}

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Car />);

Hoặc là chúng ta có thể dùng 1 state và theo dõi 1 object!

import { useState } from "react";
import ReactDOM from "react-dom/client";

function Car() {
  const [car, setCar] = useState({
    brand: "Ford",
    model: "Mustang",
    year: "1964",
    color: "red"
  });

  return (
    <>
      <h1>My {car.brand}</h1>
      <p>
        It is a {car.color} {car.model} from {car.year}.
      </p>
    </>
  )
}

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Car />);

Vì chúng ta đang theo dõi 1 object đơn, chúng ta cần tham chiếu tới object đó và thuộc tính của nó khi render ra một component. (Ví dụ: car brand)

Cập nhật Object và Mảng trong state

Khi state được cập nhật, toàn bộ state sẽ bị ghi đè.
Điều gì sẽ xảy ra nếu ta muốn cập nhật màu của xe thôi?
Nếu chúng ta gọi hàm setCar({color: "blue"}) thì brand, model và year sẽ bị loại bỏ khỏi state.
Chúng ta dùng spread operator của Javascript để xử lí vấn đề trên.

import { useState } from "react";
import ReactDOM from "react-dom/client";

function Car() {
  const [car, setCar] = useState({
    brand: "Ford",
    model: "Mustang",
    year: "1964",
    color: "red"
  });

  const updateColor = () => {
    setCar(previousState => {
      return { ...previousState, color: "blue" }
    });
  }

  return (
    <>
      <h1>My {car.brand}</h1>
      <p>
        It is a {car.color} {car.model} from {car.year}.
      </p>
      <button
        type="button"
        onClick={updateColor}
      >Blue</button>
    </>
  )
}

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Car />)

Bởi vì chúng ta cần state hiện tại, chúng ta truyền 1 hàm vào hàm setCar. Hàm này sẽ nhận giá trị trước đó.
Khi chúng ta trả về một object, spread sẽ tạo 1 shallow copy của object cũ và đè lên thuộc tính color mới.

Dịch bởi Vũ Hoài Sơn.
Link bài viết gốc: https://www.w3schools.com/react/react_usestate.asp