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;

 

 

 

posted @ 2021-02-02 00:02  shanlu  阅读(297)  评论(0编辑  收藏  举报