赞
踩
react的class类组件中,使用Reducer可以进行全局的状态管理,但是Reducer文件本身过于臃肿,逻辑解构比较复杂,学习的难度较大,于是可以通过使用函数组件的hooks来实现比较简单的状态管理。
在react函数组件中,使用hooks语法可以轻松实现许多功能,但其有一个缺陷便是hooks不具备直接进行状态管理的能力,因此要想在hooks中进行状态管理,就必须借助一些重要的API,比如createContext、useContext、useReducer等。下面介绍hooks全局状态管理的实现过程:
案例:制作一个组件Demo,包含子组件Color,Color中又包含子组件ShowText和Buttons。要求实现功能:通过点击组件Buttons内部的按钮,改变组件ShowText内的文本的颜色。
通过下图可展示这些组件之间的逻辑关系:
(1)在控制文本颜色信息的组件Color中包含了ShowText和Buttons两个组件,其中组件ShowText负责展示文本的颜色变化情况,组件Buttons负责控制改变ShowText的文本颜色。
(2)在父组件Color中共享出去了两个东西:color和reducerhan'shu,在子组件ShowText中订阅color,在子组件Buttons中订阅reducer函数。
(3)通过调用Buttons组件中订阅的reducer函数传入必要的参数,即可更新color的状态,组件ShowText的文本颜色也会随之发生改变。
- import React from "react"
- import Buttons from "./Buttons.js"
- import ShowText from "./ShowText.js"
- import {Color} from "./Colors.js"
- function Demo7(){
- return(
- <div>
- <Color>
- {/*父组件在调用Color组件的时候,传的参数是两个组件
- :ShowText和Buttons,而且没有给props定义属性
- 直接在子组件里面写的,所以子组件拿到参数
- 就直接用props.childern就行了*/}
- <ShowText></ShowText>
- <Buttons></Buttons>
- </Color>
- </div>
- )
- }
- export default Demo7
父组件Demo7在调用子组件Color的时候,传了两个参数:组件ShowText和组件Buttons,所以在子组件Color中应以props.children进行参数的接收
- // 引入依赖
- import {createContext,useReducer} from "react"
-
- // 创建并导出react上下文:此处是以对象的形式创建导出
- export const ColorContext = createContext({})
-
- // 创建,导出action.type意愿
- export ChangeColor = "ChangeColor "
-
- // 创建、导出组件Color
- export function Color(props){
- console.log(props)
- const [color,dispatch] = useReducer((state,action)=>{
- switch(action.type){
- case "ChangeColor":
- return action.color
- default:
- return state
- }
- },"blue")
- // 对外提供,子组件订阅
- return(
- <div>
- {/*向子组件传递的上线文是对象:{color:"blue"}*/}
- <ColorContext.Provider value={{color,dispatch}}>
- {props.children} {/*这是子组件*/}
- </ColorContext.Provider>
- </div>
- )
- }
组件Color通过createContext提供的Provide方法,向外暴露了color和dispatch这两个上下文信息,其子组件需使用useContext方法进行信息的订阅和获取
- import React,{useContext} from "react"
- // 该组件是按钮组件用于改变颜色
- import {ChangeColor} from "./Colors.js"
- import {ColorContext} from "./Colors.js"
- function Buttons(){
- console.log(ChangeColor)
-
- const DISPATCH = useContext(ColorContext)
- console.log(DISPATCH)
- // 然后在button里面调用DISPATCH上下文中的dispatch方法
- return(
- <div>
- <button onClick={()=>{
- DISPATCH.dispatch({
- type:"ChangeColor",
- color:"red",
- })
- }}>红色</button>
- <button onClick={()=>{
- DISPATCH.dispatch({
- type:"ChangeColor",
- color:"purple",
- })
- }}>紫色</button>
- </div>
- )
- }
- export default Buttons
- import React,{useContext} from "react"
- // 该组件用户展示文本的初始颜色
- import {ColorContext} from "./Colors.js"
-
- function ShowText(){
- // 订阅颜色
- const {color} = useContext(ColorContext)
- console.log(color)
- return(
- /**
- * 这里Color父组件调用子组件ShowText,获取到的颜色是另一个子组件Buttons通过传入参数:action{type:,color:}
- 来调用父组件组件Color中createContext的Provide提供的dipatch函数来修改更新后得到的新的颜色
- */
- <div style={{color:{color}.color}}>
- <h2>自己初始的颜色:蓝色</h2>
- </div>
- )
- }
- export default ShowText
通过点击Buttons组件中的按钮,调用reducer函数,传入颜色参数,就可以修改全局的color状态了,同时组件ShowText上的文本颜色也会变成与之对应的颜色,实现reducer状态管理的功能。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。