react中的hook

react 中的 hook

useReducer

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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
// 引用 useReducer
import React, { useEffect, useReducer } from "react";
import axios from "axios";

// 初始状态
let initialState = {
loading: false,
error: false,
data: [],
};

// 定义reducer,统一管理状态
const reducer = (state, action) => {
switch (action.type) {
case "init":
return {
...state,
loading: true,
error: false,
};
case "success":
return {
...state,
loading: false,
error: false,
data: action.payload,
};
case "failure":
return {
...state,
loading: false,
error: true,
};
default:
throw new Error();
}
};

// 自定义hook
const useFetchData = (url, initData) => {
// 如果有传过来的initData,设置到initialState里
initialState = {
...initialState,
data: initData || [],
};

// 使用useReducer初始化数据
const [state, dispatch] = useReducer(reducer, initialState);

const fetchData = (url) => {
dispatch({ type: "init" });

axios(url)
.then((res) => {
// 成功的状态
dispatch({ type: "success", payload: res.data });
})
.catch((error) => {
// 失败的状态
dispatch({ type: "failure" });
});
};

useEffect(() => {
fetchData(url);
}, [url]);

// ...state解出来,就是loading、error和data
return { ...state, fetchData };
};

export default useFetchData;

useContext

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
44
45
import React, { useContext } from "react";

const themes = {
light: {
foreground: "#000000",
background: "#eeeeee",
},
dark: {
foreground: "#ffffff",
background: "#222222",
},
};

// 创建一个 context 对象
const ThemeContext = React.createContext(themes.light);

function A() {
return (
// 使用ThemeContext包裹子组件
<ThemeContext.Provider value={themes.dark}>
<B />
</ThemeContext.Provider>
);
}

function B() {
return (
<div>
<C />
</div>
);
}

function C() {
// 使用useContext,就能直接读取到A组件中传递过来的value了
const theme = useContext(ThemeContext);

return (
<button style={{ background: theme.background, color: theme.foreground }}>
A直接传C
</button>
);
}

export default A;