Hooks và Function Components (ok)

https://vi.reactjs.org/docs/hooks-state.html

Nhắc nhẹ lại, function components trong React trông giống như thế này:

const Example = (props) => {
  // Bạn có thể sử dụng hooks tại đây!
  return <div />;
}

hoặc là:

function Example(props) {
  // Bạn có thể sử dụng hooks tại đây!
  return <div />;
}

Bạn có thể đã biết ở trên gọi là “stateless components”. Chúng ta sẽ thử sử dụng state trong những component này , vì vậy chúng tôi khuyến khích gọi chúng là “function components”.

Hooks không hoạt động bên trong các class. Nhưng bạn có thể sử dụng hooks thay vì dùng class.

Hook là gì?

Trong ví dụ mới này chúng ta import useState Hook từ React:

import React, { useState } from 'react';
function Example() {
  // ...
}

Hook là gì? Hook là một hàm đặc biệt cho phép bạn sử dụng các tính năng của React (mà không cần phải tạo class). Ví dụ, useState là một hook cho phép bạn thêm React state vào function components. Chúng ta sẽ tìm hiểu các hook còn lại trong các chương kế tiếp.

Khi nào tôi nên dùng hook? Nếu bạn viết một function component và nhận ra bạn cần thêm một số state vào chúng, trước đây bạn cần phải chuyển nó thành một class. Bây giờ bạn có thể sử dụng hook bên trong function component đã sẵn có. Chúng ta sẽ làm đều đó ngay bây giờ!

Khai báo một biến state

Trong một class, chúng ta khởi tạo count state về 0 bằng cách cài đặt this.state về { count: 0 } bên trong constructor:

class Example extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0
    };
  }

Bên trong một function component, chúng ta không có this, cho nên chúng ta không thể cài đặt hoặc đọc this.state. Thay vào đó, chúng ta gọi useState Hook trực tiếp bên trong component:

import React, { useState } from 'react';
function Example() {
  // Khai báo một biến state mới, gọi nó là "count"
  const [count, setCount] = useState(0);

Hàm useState làm gì khi được gọi? Nó khai báo một “state variable” (biến state). Biến này gọi là count nhưng ta có thể gọi nó với bất kì tên nào, ví dụ gọi là banana. Đây là cách để “lưu giữ” các giá trị giữa các lần gọi hàm — useState là một cách mới để sử dụng như là cách this.state được dùng trong class. Thông thường, các biến này “biến mất” khi hàm kết thúc nhưng các biến state này được React giữ lại.

Hàm useState nhận tham số gì? Tham số duy nhất được truyền vào hook useState() là state ban đầu. Không giống như khai báo với Class, state không cần thiết phải là object mà có thể là số hoặc chuỗi. Với ví dụ trên, ta chỉ cần biết người dùng click bao nhiêu lần, vì vậy ta truyền vào giá trị khởi tạo là 0. (Nếu ta muốn lưu hai giá trị khác nhau, ta sẽ gọi useState() hai lần.)

useState trả về gì? Nó trả về một cặp giá trị dưới dạng mảng: state hiện tại và một hàm để update nó. Đây là lý do chúng ta viết const [count, setCount] = useState(). Cặp này tương tự như this.state.countthis.setState trong class, khác là ta dùng chúng theo cặp. Nếu bạn không quen với cách dùng này, chúng ta sẽ quay trở lại thêm ở cuối trang.

Vậy chúng ta đã biết useState Hook để làm gì, việc đó giúp ví dụ dưới đây dễ hiểu hơn:

import React, { useState } from 'react';
function Example() {
  // Khai báo một biến state mới, gọi nó là "count"
  const [count, setCount] = useState(0);

Ví dụ trên khai báo một biến state gọi là count và set nó về 0. React sẽ nhớ giá trị hiện tại của nó và cung cấp cho hàm của chúng ta giá trị mới nhất giữa những lần re-render. Nếu chúng ta muốn cập nhật giá trị count hiện tại, có thể gọi hàm setCount.

Đọc State

Khi muốn hiển thị giá trị hiện tại của state count trong class, chúng ta đọc từ this.state.count:

<p>Bạn đã click{this.state.count} lần</p>

Trong hàm (sử dụng với hooks), chúng ta dùng trực tiếp biến count:

 <p>Bạn đã click{count} lần</p>

Updating State

Trong class, chúng ta cần gọi this.setState() để update state count:

<button onClick={() => this.setState({ count: this.state.count + 1 })}>Click vào 
  </button>

Trong hàm (sử dụng với hooks), chúng ta đã có biến setCountcount cho nên không cần this:

<button onClick={() => setCount(count + 1)}>
    Click vào 
  </button>

Mẹo: Cặp ngoặc vuông nghĩa là gì?

Có thể bạn để ý chúng ta dùng cặp ngoặc vuông khi khai báo biến state:

const [count, setCount] = useState(0);

Tên của các biến bên trái = không phải là một phần của React API. Bạn có thể đặt tên biến state bất kì:

const [fruit, setFruit] = useState('banana');

Array destructuring

const foo = ['one', 'two', 'three'];

const [red, yellow, green] = foo;
console.log(red); // "one"
console.log(yellow); // "two"
console.log(green); // "three"

Cú pháp Javascript này được gọi là “array destructuring”. Nó nghĩa là bạn đang tạo hai biến mới fruitsetFruit. Trong đó, fruit là giá trị đầu tiên trả về bởi useState, và setFruit là giá trị thứ hai. Tương ứng với đoạn code:

var fruitStateVariable = useState('banana'); // Trả về một cặp (mảng 2 phần tử)
  var fruit = fruitStateVariable[0]; // Phần tử đầu tiên
  var setFruit = fruitStateVariable[1]; // Phần tử thứ hai

Khi chúng ta khai báo một biến state với useState. Nó trả về một cặp - mảng có 2 phần tử. Phần tử đầu tiên là giá trị hiện tại, phần tử thứ hai là hàm cập nhật giá trị đó. Sử dụng [0] and [1] để truy cập chúng thì dễ gây hoang mang bởi vậy chúng có ý nghĩa nhất định. Đây là lý do chúng ta dùng array destructuring.

Mẹo: dùng nhiều biến state

Khai báo biến state dưới dạng một cặp giá trị [something, setSomething] thì tiện lợi bởi vì chúng cho phép chúng ta đặt tên biến state khác nhau nếu chúng ta muốn dùng nhiều hơn 1 state:

function ExampleWithManyStates() {
  // Declare multiple state variables!
  const [age, setAge] = useState(42);
  const [fruit, setFruit] = useState('banana');
  const [todos, setTodos] = useState([{ text: 'Learn Hooks' }]);

Trong component ở trên, chúng ta có các biến/state cục bộ age, fruit, và todos. Và chúng ta có thể cập nhật chúng riêng rẽ:

 function handleOrangeClick() {
    // Similar to this.setState({ fruit: 'orange' })
    setFruit('orange');
  }

Bạn không cần thiết phải sử dụng nhiều biến state. Biến state có thể chứ dữ liệu dạng đối tượng và mảng. Vì vậy bạn có thể nhóm các dữ liệu liên quan với nhau vào cùng một biến. Tuy nhiên, không giống như this.setState trong class, cập nhật biến state luôn luôn thay thế mà không trộn chúng lại (giống như setState).

Bước kế tiếp

Ở chương này chúng ta đã tìm hiểu về một trong các hook cung cấp bởi React, gọi là useState. Thỉnh thoảng chúng ta gọi chúng là State Hook. Nó cho phép thêm state cục bộ vào React function component — lần đầu làm chuyện ấy!

Chúng ta cũng tìm hiểu một chút về các hook. Hook là các hàm cho phép bạn “móc” các tính năng của React vào function components. Tên của chúng luôn bắt đầu với use, có nhiều hook mà chúng ta chưa khám phá.

Last updated

Was this helpful?