Dạo này có thêm nhiều thời gian để fix bug cho mấy dự án cá nhân, client của mình la làng quá trời luôn =)))

Custom hooks là gì?

Custom Hooks là những hooks đã được custom, hay nói cách khác là chúng ta sẽ tạo ra những hook mới ngoài những hook cơ bản mình để cập ở các bài viết như useRef, useState…

Bằng một vài đường google bạn có thể tìm hiểu được như sau:

Một custom hooks là:

  • Là một function, nhận input và trả output.
  • Tên của nó thường bắt đầu bởi use như useScreen, useCount,…
  • Khác với functional component, custom hooks trả về một dữ liệu bình thường, không phải là jsx.
  • Khác với function bình thường, custom hooks có thể sử dụng các hooks khác như useState, useRef,.. và cả các custom hooks khác nếu có và nếu muốn.

Có thể bạn không để ý, các thư viện cho ReactJS cũng cung cấp các hooks cho chúng ta dùng như useForm (React Hook Form), useMediaQuery (MUI), … cũng là các custom hooks.

Tại sao lại sử dụng custom hooks?

Lý do quan trọng và nghiêm trọng nhất:

  • Tách biệt hoàn toàn logic với functional component.
  • Tái sử dụng ở nhiều nơi.

Và lý do ít quan trọng hơn với bạn nhưng quan trọng hơn với các sếp:

  • Component nhìn clean hơn.
  • Dễ maintain về sau hơn.

Khi nào thì dùng custom hooks?

Khi…

  • Một đoạn code (logic) được tái sử dụng nhiều nơi, và có thể bạn sẽ cần dùng tới react hooks.
  • Logic quá dài và phức tạp để cho component hiện tại của bạn trông đẹp hơn.

Ví dụ

Hí hí, vẫn là ví dụ cổ điển từ hôm useState đến giờ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import { useState } from "react";

function useTroll(count) {
let _result = 0;
for (let _i = 0; _i < count * 500000000; _i++) {
_result += _i;
}
return _result;
}

export default function App() {
const [count, setCount] = useState(0);
const [randomID, setRandomID] = useState();
const troll = useTroll(count);
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<button onClick={() => setCount(count + 1)}>+</button>
<div>count: {count}</div>
<button onClick={() => setRandomID(Math.round(Math.random() * 10))}>
random
</button>
<div>randomID: {randomID}</div>
<div>troll: {troll}</div>
</div>
);
}

Mình vừa tạo ra một custom hook là useTroll, nhưng ở trường hợp này dùng custom hooks thì ngu quá (Vì nếu như vậy thà dùng function bình thường) nên mình sửa lại cho nó chuyện nghiệp hơn

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
import { useState, useEffect } from "react";

const sleep = (ms) => new Promise((r) => setTimeout(r, ms));

function useTroll(count) {
const [isLoading, setIsLoading] = useState(false);
const [data, setData] = useState(0);

useEffect(() => {
(async () => {
setIsLoading(true);
await sleep(count * 1000);
let _result = 0;
for (let _i = 1; _i <= count; _i++) {
_result += _i;
}
setData(_result);
setIsLoading(false);
})();
}, [count]);

return { isLoading, data };
}

export default function App() {
const [count, setCount] = useState(0);
const [randomID, setRandomID] = useState();
const { isLoading, data } = useTroll(count);

if (isLoading) return "loadingggggg";
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<button onClick={() => setCount(count + 1)}>+</button>
<div>count: {count}</div>
<button onClick={() => setRandomID(Math.round(Math.random() * 10))}>
random
</button>
<div>randomID: {randomID}</div>
<div>troll: {data}</div>
</div>
);
}

Giờ mình đổi tí func để mỗi lần troll thì nó sleep lại và show ra loadding nhé =))) Giờ custom hooks useTroll của mình dùng cả useState và useEffect rồi nên nó xứng đáng là cái custom hooks rồi nè.

Hịn hò hơn rồi đúng không nào =))

https://s8.gifyu.com/images/CPT2206221716-786x215.gif