• useReducer + useContext 实现 Redux


    useContext:可以访问全局状态,避免一层层的传递状态,这符合 Redux 的一项规则,就是状态全局化,并能统一管理。

    useReducer:通过 action 的传递,更新复杂逻辑的状态,主要是可以实现类似 Redux 中的 Reducer 部分,实现业务逻辑的可行性。

    第一步,使用 useContext 实现状态共享

    ①编写UI 组件

    showArea.js (整个显示区域)

    import React from 'react'
    import Text from './showText'
    import Button from './buttons'
    
    function showArea(){
        return (
            <div>
               <Text/>
               <Button/>
            </div>
        )
    }
    export default showArea;
    

    showText.js 中 的 Text 组件

    import React from 'react'
    
    function Text() {
        return (
            <h3 style={{ color: 'blue' }}>字体颜色是blue</h3>
        )
    }
    export default Text;
    

    buttons.js 中的 Button 组件

    import React from 'react'
    
    function Button() {
        return (
            <div>
                <button>红色</button>
                <button>绿色</button>
            </div>
        )
    }
    export default Button;
    

    ② 利用userContext 编写颜色共享组件 color.js

    //颜色共享组件 color.js
    import React , {createContext} from 'react'
    
    export const ColorContext = createContext({}) 
    
    function Color(props){
        return (
            <ColorContext.Provider value={{color:"red"}}>
               {props.children}
            </ColorContext.Provider>
        )
    }
    export default Color;
    

    引入了 createContext 用来创建上下文 ColorContext 组件,然后我们要用 { props.children }   来显示对应的子组件(Text 和 Button 组件)

    改写 ShowArea 组件,让它可以共享状态,Text 和 Button 组件 共享 Color 组件的状态

    import React from 'react'
    import Text from './showText'
    import Button from './buttons'
    import Color from './color'
    
    function ShowArea(){
        return (
            <div>
              <Color>
                 <Text />
                 <Button />
              </Color>
            </div>
        )
    }
    export default ShowArea;

    改写 Text 组件,引入  useContext 和 在 color.js 中声明的 ColorContext ,让组件可以接受全局变量 color 

    import React ,{useContext} from 'react'
    import {ColorContext} from './color'
    
    function Text() {
        const {color} = useContext(ColorContext)
        return (
            <h3 style={{ color: color}}>字体颜色是{color}</h3>
        )
    }
    export default Text;

    这就通过 useContext 实现了状态的共享

     第二步,使用 useReducer 控制业务逻辑

    颜色管理的代码都放在了 color.js 中共,所以在文件里添加一个 reducer,用于处理颜色更新的逻辑。先声明一个 reducer 的函数,它就是 javascript 中的普通函数。有了 reducer后,在 color 组件里使用 useReducer ,这样Color 组件就有了那个共享状态和处理业务逻辑的能力,跟以前使用的 redux 几乎一样了。

    import React , {createContext,useReducer} from 'react'
    
    export const ColorContext = createContext({}) 
    export const COLORCHANGE = 'COLORCHANGE'
    
    const reducer=(state,action)=>{ 
        switch(action.type){
            case COLORCHANGE:
                return action.color
            default:
                return state
        }
    }
    
    function Color(props){
        const [color,dispatch] = useReducer(reducer,'green')
        return (
            <ColorContext.Provider value={{color,dispatch}}> {/*color和dispatch都共享出去*/}
               {props.children} 
            </ColorContext.Provider>
        )
    }
    export default Color;

    通过 dispatch 修改状态:

    在 Button 组件中使用 dispatch 完成按钮的相应操作。先引入 useContext,ColorContext 和 COLORCHANGE ,然后写 onClick 事件就可以了

    import React , {useContext} from 'react'
    import {ColorContext,COLORCHANGE} from './color'
    
    function Button() {
        const {dispatch} = useContext(ColorContext) //dispatch 是在ColorContext组件中共享出去的
    
        return (
            <div>
                <button onClick={()=>dispatch({type:COLORCHANGE,color:'red'})}>红色</button>
                <button onClick={()=>dispatch({type:COLORCHANGE,color:'green'})}>绿色</button>
            </div>
        )
    }
    export default Button;

     

  • 相关阅读:
    Excel导入导出DataGridView
    博客开通第一天
    windows10 VM12 安装Mac OS X 10.11
    js判断IE浏览器及版本
    C# MD5 加密
    WindowsErrorCode
    localStorage,sessionStorage的使用
    js实现页面锚点定位动画滚动
    纯js实现页面返回顶部的动画
    HTML table固定表头
  • 原文地址:https://www.cnblogs.com/shanlu0000/p/13129980.html
Copyright © 2020-2023  润新知