#Aizz, #Aizz… Chỉ có 13 hooks thôi mà sao nó lâu thế nhỉ :((((

useContext(context)

Khái niệm

À, useContext được xếp vào basic hooks nhé

Accepts a context object (the value returned from React.createContext) and returns the current context value for that context. The current context value is determined by the value prop of the nearest <MyContext.Provider> above the calling component in the tree.

Chức năng

Tương tự useState, useContext là một hooks giúp chúng ta có thể làm việc với react context trong một functional component.

1
2
3
4
// class component
const value = this.context;
// functional compoent
const value = useContext(AppContext);

Ví dụ

Hí hí, vẫn là ví dụ truyền thống của chuỗi series này nên ví du nó có nhảm thế nào đi nữa thì các bạn cũng đừng để ý =))) :

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
import { useState, createContext, useContext } from "react";

const CountContext = createContext();

const Troll = () => {
const count = useContext(CountContext);
const troll = (_count) => {
let _result = 0;
for (let _i = 0; _i < _count * 500000000; _i++) {
_result += _i;
}
return _result;
};
return (
<>
<div>count: {count}</div>
<div>troll: {troll(count)}</div>
</>
);
};

export default function App() {
const [count, setCount] = useState(1);
const [randomID, setRandomID] = useState();
const updateCount = () => setCount(count + 1);
return (
<CountContext.Provider value={count}>
<h1>Hello CodeSandbox</h1>
<button onClick={() => updateCount()}>+</button>
<Troll />
<button onClick={() => setRandomID(Math.round(Math.random() * 10))}>
random
</button>
<div>randomID: {randomID}</div>
</CountContext.Provider>
);
}

Các bạn thấy đó, component <Troll /> của mình hiện tại không truyền count vào như ở ví dụ usememo-va-usecallback nhưng nó vẫn hoạt động tốt đúng không nào :3

useReducer(state, action)

Chắc bây giờ các bạn đang nhảy số trong đầu, tại sao useReducer lại được xếp chung buổi với useContext đúng không nào. Và câu trả lời là: - Vì mình thích =))) Thật ra thì nên để nó nằm chung với useState nhưng mà mình thích để useState với useRef hơn :3

Khái niệm

An alternative to useState. Accepts a reducer of type (state, action) => newState, and returns the current state paired with a dispatch method. (If you’re familiar with Redux, you already know how this works.)

Chức năng

Cũng được dùng để quản lý state giống như useState thôi, nhưng thay vì trả về state, và setState giống như useState thì nó trả về như thế nầy đây.

1
const [state, dispatch] = useReducer(reducer, initialState);

Ví dụ

Tất nhiên là với một hooks có chức năng tương tự useState thì mình sẽ lấy ví dụ ở Ví dụ useState:

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
import { useState, useReducer } from "react";

const countReducer = (count, action) => {
switch (action.type) {
case "INCREASE":
return count + 1;
default:
throw new Error();
}
};

export default function App() {
const [count, countDispatch] = useReducer(countReducer, 0);
const [randomID, setRandomID] = useState();

const troll = (_count) => {
let _result = 0;
for (let _i = 0; _i < _count * 500000000; _i++) {
_result += _i;
}
return _result;
};

return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<button onClick={() => countDispatch({ type: "INCREASE" })}>+</button>
<div>count: {count}</div>
<button onClick={() => setRandomID(Math.round(Math.random() * 10))}>
random
</button>
<div>randomID: {randomID}</div>
<div>troll: {troll(count)}</div>
</div>
);
}

Và tất nhiên chức năng nó cũng chả khác gì so với ví dụ ở useState cả :3

Kết hợp giữa useContext với useReducer

Hí hí, riêng bài này thì mình không so sánh giữa useContext với useReducer, vì nó có điểm chung gì đâu mà so sánh… Nhưng mà mình sẽ ví dụ cách kết hợp giữa 2 bọn nó để đánh bật redux ra khỏi thế giới (Hoặc không) =)))

Định viết nhưng nó dài quá, thôi mình sẽ để ở bài viết khác nhé :3

Kết luận

useContextuseReducer có cảm giác như chẳng liên quan gì đến nhau nhưng nếu dùng chung với nhau một cách hợp lý, bạn có thể “fake” redux ở một khía cạnh nào đó, mình sẽ cố gắng viết bài này sớm nhất trong phạm vi có thể. Chắc chắn là sẽ sau series hooks ký sự.