P07:用useReducer实现Redux效果的小案例
Posted wgchen~
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P07:用useReducer实现Redux效果的小案例相关的知识,希望对你有一定的参考价值。
阐述
在实际使用中,useContext 和 useReducer是可以实现类似Redux的效果,并且一些简单的个人项目,完全可以用下面的方案代替Redux,这种做法要比Redux简单一些。
因为 useContext 和 useReducer在我之前的文章中已经学习过了,所以我们把精力就放在如何模拟出Redux的效果。如果你目前还没掌握基本的语法,可以再复习一下前面两篇文章的知识点。
理论上的可行性
我们先从理论层面看看替代Redux的可能性,其实如果你对两个函数有所了解,只要我们巧妙的结合,这种替代方案是完全可行的。
1、useContext:可访问全局状态,避免一层层的传递状态。这符合Redux其中的一项规则,就是状态全局化,并能统一管理。
2、useReducer:通过action的传递,更新复杂逻辑的状态,主要是可以实现类似Redux中的Reducer部分,实现业务逻辑的可行性。
经过我们在理论上的分析是完全可行的,接下来我们就用一个简单实例来看一下具体的实现方法。
那我们先实现useContext部分(也就是状态共享),再继续实现useReducer部分(控制业务逻辑)。
先看一下今天的案例效果:
编写基本UI组件
在 /src
目录下新建一个文件夹 example6
,有了文件夹后,在文件夹下面建立一个ShowArea.js
文件。
代码如下:
ReactHooksDemo\\demo01\\src\\example6\\ShowArea.js
import React from 'react';
function ShowArea()
return (<div style=color:'blue'>字体颜色为blue</div>)
export default ShowArea
显示区域写完后,新建一个Buttons.js
文件,用来编写按钮,这个是两个按钮,一个蓝色一个黄色。先不写其他任何业务逻辑。
ReactHooksDemo\\demo01\\src\\example6\\Buttons.js
import React from 'react';
function Buttons()
return (
<div>
<button>蓝色</button>
<button>黄色</button>
</div>
)
export default Buttons
然后再编写一个组合他们的 Example6.js
组件,引入两个新编写的组件 ShowArea
和Buttons
,并用 <div>
标签给包裹起来。
import React, useReducer from 'react';
import ShowArea from './example6/ShowArea';
import Buttons from './example6/Buttons';
function Example6()
return (
<div>
<ShowArea />
<Buttons />
</div>
)
export default Example6
这步做完,需要到 /src
目录下的 index.js
中引入一下 Example6.js
文件,引入后React才能正确渲染出刚写的UI组件。
ReactHooksDemo\\demo01\\src\\index.js
import React from 'react';
import ReactDOM from 'react-dom';
import Example from './Example6';
ReactDOM.render(<Example />, document.getElementById('root'));
做完这步可以简单的预览一下UI效果,虽然很丑,但是只要能满足学习需求就可以了。
我们虽然都是前端,但是在学习时没必要追求漂亮的页面,关键时把知识点弄明白。我们写这么多文件,也就是要为接下来的知识点服务,其实这些组件都是陪衬罢了。
编写颜色共享组件color.js
有了UI组件后,就可以写一些业务逻辑了,接下来我们先实现状态共享,这个就是利用useContext。在example6文件夹下建立一个Color.js文件,然后写入下面的代码。
ReactHooksDemo\\demo01\\src\\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
进行改写,让她可以共享状态。
ReactHooksDemo\\demo01\\src\\Example6.js
import React from 'react';
import ShowArea from './example6/ShowArea';
import Buttons from './example6/Buttons';
import Color from './example6/Color'; //引入Color组件
function Example6()
return (
<div>
<Color>
<ShowArea />
<Buttons />
</Color>
</div>
)
export default Example6
然后再改写 showArea.js
文件,我们会引入 useContext
和在 color.js
中声明的ColorContext
,让组件可以接收全局变量。
ReactHooksDemo\\demo01\\src\\example6\\ShowArea.js
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实现了Redux状态共享的能力,这节课看一下如何使用useReducer来实现业务逻辑的控制。
在color.js中添加Reducer
颜色(state)管理的代码我们都放在了 color.js
中,所以在文件里添加一个reducer,用于处理颜色更新的逻辑。
先声明一个reducer的函数,它就是javascript中的普通函数,在讲useReducer的时候已经详细讲过了。
有了reducer后,在Color组件里使用useReducer,这样Color组件就有了那个共享状态和处理业务逻辑的能力,跟以前使用的Redux几乎一样了。
之后修改一下共享状态。我们来看代码:
ReactHooksDemo\\demo01\\src\\example6\\Color.js
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来完成按钮的相应操作了。
先引入 useContext、ColorContext 和 UPDATE_COLOR,然后写onClick事件就可以了。
代码如下:
ReactHooksDemo\\demo01\\src\\example6\\Buttons.js
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
这样代码就编写完成了,用 useContext 和 useReducer 实现了Redux的效果,这个代码编写过程比Redux要简单,但是也是有一定难度的。
以上是关于P07:用useReducer实现Redux效果的小案例的主要内容,如果未能解决你的问题,请参考以下文章
如何将 React Context API 与 useReducer 一起使用以遵循与 Redux 类似的风格 [关闭]