React Hooks 05
useContext()和 useReducer()配合使用可以减少组件层级
useContext()
useContext()会创建一个上下文对象,对外暴露消费者和生产者,在上下文之内的所有子组件都可以访问这个上下文环境之内的数据
简单的说 context 就是对他所包含的组件树提供全局共享数据的技术
缺点:
- 增加调试复杂度,很难跟踪某个 context 的变化是如何产生的
- 让组件复用变得困难,因为一个组件使用 context,他必须确保被用到的地方必须有个 context 的 provider 在父组件上
代码:
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
| import React, { useState, useContext } from "react";
const themes = { light: { foreground: "#000000", background: "#eeeeee", }, dark: { foreground: "#ffffff", background: "#222222", }, }; const ThemeContext = React.createContext(themes.light);
function ThemedButton(props) { const theme = useContext(ThemeContext); const [themes, setthemes] = useState(theme.dark);
return ( <div> <div style={{ width: "100px", height: "100px", background: themes.background, color: themes.foreground, }} ></div> <button onClick={() => setthemes(theme.light)}>Light</button> <button onClick={() => setthemes(theme.dark)}>Dark</button> </div> ); }
const ToolBar = () => { return ( <ThemeContext.Provider value={themes}> <ThemedButton /> </ThemeContext.Provider> ); };
export default ToolBar;
|
useReducer()
工作流程:
![image-20220801182429851](https://cdn.jsdelivr.net/gh/chiguayeshao/pic-bed/image-20220801182429851.png)
代码:
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
| import React, { useReducer } from "react";
const AddAndMinus = () => { const initState = { count: 0, };
const reducer = (preState, action) => { switch (action.type) { case "add": return { count: preState.count + 1 }; case "minus": return { count: preState.count - 1 }; default: return preState; } };
const [state, dispatch] = useReducer(reducer, initState);
return ( <div> <button onClick={() => { dispatch({ type: "add", }); }} > + </button> {state.count} <button onClick={() => { dispatch({ type: "minus", }); }} > - </button> </div> ); };
export default AddAndMinus;
|
特点:
- 代码变长,但理解起来更简洁明了,拥有更好的可读性
- reducer 可以将逻辑与 ui 分离
- state 都集中到 reducer 中进行处理,更容易复用 state 逻辑变化代码,特别对于 state 变化很复杂的场景
- 深层子组件需要修改一些状态,state 变化复杂,一个操作需要修改很多 state,ui 与业务分开维护,优先考虑使用 reducer