React 组件通信 03
非嵌套组件通信
Hooks
开发过程中会遇到这样一个场景 FirstChild 和 SecondChild 是我们的两个组件,FirstChild 组件 dispatch action,在 SecondChild 组件展示变化的数据,那么就需要在两个字组件之上一层来设计 context
- 首先建立 context,存储一个初始状态和一个变更 state 的状态管理器
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| export const defaultState = { value: 0, }; export function reducer(state, action) { switch (action.type) { case "ADD": return { ...state, value: state.value + 1 }; case "REDUCE": return { ...state, value: state.value - 1 }; default: throw new Error(); } }
|
- 需要显性的声明 Context.Provider 把数据传给包裹组件,这就需要使用 useReducer,我们把 reducer 和默认 state 作为 useReducer 的参数传入
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| import React, { useReducer, createContext } from "react"; import FirstChild from "./FirstChild"; import SecondChild from "./SecondChild"; import { reducer, defaultState } from "./Context"; export const Context = createContext(null); export function Content() { const [state, dispatch] = useReducer(reducer, defaultState); return ( <Context.Provider value={{ state, dispatch: dispatch }}> <FirstChild /> <SecondChild /> </Context.Provider> ); }
|
- 组件 FirstChild 有两个按钮‘ADD’和‘REDUCE’,点击两个按钮分别进行加 1 减 1 操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| import React, { useContext } from "react"; import { Context } from "./Content"; function FirstChild() { const AppContext = useContext(Context); return ( <div> <button onClick={() => { AppContext.dispatch({ type: "ADD" }); }} > ADD </button> <button onClick={() => { AppContext.dispatch({ type: "REDUCE" }); }} > REDUCE </button> </div> ); } export default FirstChild;
|
- 组件 SecondChild 展示当前 state.value
1 2 3 4 5 6 7
| import React, { useContext } from "react"; import { Context } from "./Content"; function SecondChild() { const AppContext = useContext(Context); return <div>{AppContext.state.value}</div>; } export default SecondChild;
|
Redux
Redux 是一个独立的事件通讯插件,Redux 的基本原理实际上就是围绕着 store 进行的,这个 store 是通过 createStore()方法创建的,他具有唯一性,可以认为是整个应用的数据存储中心,集中了大部分页面需要的状态数据。想要改变 state 的唯一方法就是出发 Action,Reducer 接收到 Action 并更新数据 store。按照这个思想,Redux 适用于多交互,多数据源的场景。
订阅发布模式
前文讲过订阅发布模式 [设计模式 订阅发布 | SunleDog](https://sunle.dog/2022/02/03/设计模式 订阅发布/)