P07:用useReducer实现Redux效果的小案例

在实际使用中,useContextuseReducer是可以实现类似Redux的效果,并且一些简单的个人项目,完全可以用下面的方案代替Redux,这种做法要比Redux简单一些。因为useContextuseReducer在我之前的文章中已经学习过了,所以我们把精力就放在如何模拟出Redux的效果。如果你目前还没掌握基本的语法,可以再复习一下前面两篇文章的知识点。

理论上的可行性

我们先从理论层面看看替代Redux的可能性,其实如果你对两个函数有所了解,只要我们巧妙的结合,这种替代方案是完全可行的。

  1. useContext:可访问全局状态,避免一层层的传递状态。这符合Redux其中的一项规则,就是状态全局化,并能统一管理。
  2. useReducer:通过action的传递,更新复杂逻辑的状态,主要是可以实现类似Redux中的Reducer部分,实现业务逻辑的可行性。

经过我们在理论上的分析是完全可行的,接下来我们就用一个简单实例来看一下具体的实现方法。那我们先实现useContext部分(也就是状态共享),再继续实现useReducer部分(控制业务逻辑)。

先看一下今天的案例效果:

P07:用useReducer实现Redux效果的小案例

编写基本UI组件

/src目录下新建一个文件夹example6,有了文件夹后,在文件夹下面建立一个ShowArea.js文件。代码如下:

import React from 'react';
function ShowArea(){

    return (<div style={{color:'blue'}}>字体颜色为blue</div>)

}
export default ShowArea

显示区域写完后,新建一个Buttons.js文件,用来编写按钮,这个是两个按钮,一个蓝色一个黄色。先不写其他任何业务逻辑。

import React from 'react';

function Buttons(){
    return (
        <div>
            <button>蓝色</button>
            <button>黄色</button>
        </div>
    )
}

export default Buttons

然后再编写一个组合他们的Example6.js组件,引入两个新编写的组件ShowAreaButtons,并用<div>标签给包裹起来。

import React, { useReducer } from 'react';
import ShowArea from './ShowArea';
import Buttons from './Buttons';

function Example6(){
    return (
        <div>
            <ShowArea />
            <Buttons />
        </div>
    )
}

export default Example6

这步做完,需要到/src目录下的index.js中引入一下Example6.js文件,引入后React才能正确渲染出刚写的UI组件。

import React from 'react';
import ReactDOM from 'react-dom';
import Example from './Example6/Example6'

ReactDOM.render(<Example />, document.getElementById('root'));

做完这步可以简单的预览一下UI效果,虽然很丑,但是只要能满足学习需求就可以了。我们虽然都是前端,但是在学习时没必要追求漂亮的页面,关键时把知识点弄明白。我们写这么多文件,也就是要为接下来的知识点服务,其实这些组件都是陪衬罢了。

编写颜色共享组件color.js

有了UI组件后,就可以写一些业务逻辑了,接下来我们先实现状态共享,这个就是利用useContext。在example6文件夹下建立一个Color.js文件,然后写入下面的代码。

import React, { createContext } from 'react';

export const ColorContext = createContext({})

export const Color = props => {
    return (
        <ColorContext.Provider value={{color:"red"}}>
            {props.children}
        </ColorContext.Provider>
    )
}

代码中引入了createContext用来创建共享上下文ColorContext组件,然后我们要用{props.children}来显示对应的子组件。

有了这个组件后,我们就可以把Example6.js进行改写,让她可以共享状态。

import React from 'react';
import ShowArea from './ShowArea';
import Buttons from './Buttons';
import { Color } from './color';   //引入Color组件

function Example6(){
    return (
        <div>
            <Color>
                <ShowArea />
                <Buttons />
            </Color>
        </div>
    )
}

export default Example6

然后再改写showArea.js文件,我们会引入useContext和在color.js中声明的ColorContext,让组件可以接收全局变量。

import React , { useContext } from 'react';
import { ColorContext } from './color';

function ShowArea(){
    const {color} = useContext(ColorContext)
    return (<div style={{color:color}}>字体颜色为{color}</div>)

}

export default ShowArea

这时候就通过useContext实现了状态的共享,可以到浏览器中看一下效果。

useContext实现了状态的共享


上面我们用useContext实现了Redux状态共享的能力,这节课看一下如何使用useReducer来实现业务逻辑的控制。

在color.js中添加Reducer

颜色(state)管理的代码我们都放在了color.js中,所以在文件里添加一个reducer,用于处理颜色更新的逻辑。先声明一个reducer的函数,它就是JavaScript中的普通函数,在讲useReducer的时候已经详细讲过了。有了reducer后,在Color组件里使用useReducer,这样Color组件就有了那个共享状态和处理业务逻辑的能力,跟以前使用的Redux几乎一样了。之后修改一下共享状态。我们来看代码:

import React, { createContext,useReducer } from 'react';

export const ColorContext = createContext({})

export const UPDATE_COLOR = "UPDATE_COLOR"

const reducer= (state,action)=>{
    switch(action.type){
        case UPDATE_COLOR:
            return action.color
        default:
            return state
    }
}

export const Color = props=>{
    const [color,dispatch]=useReducer(reducer,'red')
    return (
        <ColorContext.Provider value={{color,dispatch}}>
            {props.children}
        </ColorContext.Provider>
    )
}

注意,这时候我们共享出去的状态变成了color和dispatch,如果不共享出去dispatch,你是没办法完成按钮的相应事件的。

通过dispatch修改状态

目前程序已经有了处理共享状态的业务逻辑能力,接下来就可以在Buttons.js使用dispatch来完成按钮的相应操作了。先引入useContextColorContextUPDATE_COLOR,然后写onClick事件就可以了。代码如下:

import React ,{useContext} from 'react';
import {ColorContext,UPDATE_COLOR} from './color'

function Buttons(){
    const { dispatch } = useContext(ColorContext)
    return (
        <div>
            <button onClick={()=>{dispatch({type:UPDATE_COLOR,color:"blue"})}}>蓝色</button>
            <button onClick={()=>{dispatch({type:UPDATE_COLOR,color:"yellow"})}}>黄色</button>
        </div>
    )
}

export default Buttons

这样代码就编写完成了,用useContextuseReducer实现了Redux的效果,这个代码编写过程比Redux要简单,但是也是有一定难度的。希望第一次接触的小伙伴能自己动手写5遍以上,把这种模式掌握好,因为在工作中经常用到。

1. 本站所有免费资源来源于用户上传和网络,因此不包含技术服务请大家谅解!如有侵权请邮件联系客服!
2. 本站不保证所提供下载的免费资源的准确性、安全性和完整性,免费资源仅供下载学习之用!如有链接无法下载、失效,请联系客服处理!
3. 您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容资源!如用于商业或者非法用途,与本站无关,一切后果请用户自负!
4. 如果您也有好的资源或技术教程,您可以投稿发布,成功分享后有站币奖励和额外收入!
5. 加入前端开发QQ群:565733884,我们大家一起来交流技术!
码云笔记 » P07:用useReducer实现Redux效果的小案例

发表评论

提供最优质的资源集合

立即查看 了解详情