Flux与Redux
基于React的比较重要的思想和库,这里也简单的写个博客记录一下学习过程
Flux架构说到底就是一种思想,就比如说我们写一个组件的时候,就很容易在一个组件内又写请求数据的函数又把这些数据展示出来,就会让一个组件显得很长很长,但其实业务逻辑不需要关心数据从哪里来,只需要定义好传入的接口就行了,数据应该抽象到其他地方去做,比如把数据抽象到父组件中去。这样就完成了数据请求和业务逻辑的分开。我们称只有数据请求的组件叫容器型组件,而只有业务逻辑没有数据请求的组件叫展示型组件。这样抽象后的代码是具有更多的可读性和可维护性,但是!!!!这不是最佳的办法,因为请求数据这部分还是写在了组件当中,数据与逻辑解耦才是我们真正想要的!这是,Flux架构就来了。
Flux架构
Flux可以说是MVC模式的一种变体,更为清晰和简单,对于MVC可以自行搜索了解。Flux的核心思想就是数据和逻辑永久单向流动我们看一下他的流程图
详细点就是
简单的用语言说就是:
- 用户访问 View
- View 发出用户的 Action
- Dispatcher 收到 Action,要求 Store 进行相应的更新
- Store 更新后,发出一个”change”事件
- View 收到”change”事件后,更新页面
Redux
简单的了解了Flux后,我们就看看Redux,Redux就是基于Flux架构实现的一个react库,用于集中式管理状态,我们先看看他的原理图
- 这个原理图就是,比如我们在UI界面端点击了一个按钮,要把这个按钮从白色变成红色,在我们点击后会触发点击时间,调用了store.dispath()方法把一个action传给store,然后store就会再帮我们调用reducer函数。reducer是个纯函数,他会根据action修改相应的状态并返回给store,然后store更新状态,我们button的颜色就会相应更改了(store.getState())
我们用形象点的语言来解释一下
- 我们是顾客,去一个饭店吃饭,ReactComponents就是菜单,是我们能看到的UI图,然后我们点菜,就会告诉店小二我们要吃啥,这个店小二就是ActionCreators,店小二就会拿着我们的想要的食物(action)去告诉(dispatch)老板,老板就是store,然后老板再把这个消息告诉后厨(Reducers),后厨知道我们要吃啥了,就刷刷刷加工给我们上食材(返回新状态)。
重点API
- store.getState() 获取状态
- store.dispatch() 更改状态
- store.subscribe() 监听状态的改变
注意中间件的使用!并且中间件一般是是在dispatch里生效的
react-redux
就是 Facebook团队基于redux的影响出了一个可以更好的使用redux的一个库。
重点有如下API
- connect()
- <Provider/>组件
先看看react-redux的模型图
react-redux中把一个组件拆开,分成UI组件和容器组件(更贴合于Flux架构),然后UI组件不接受任何业务逻辑,就类似与纯函数,他就像一个“纯组件”,只通过接受过来的props参数来改变渲染结果,然后Count组件就负责承担业务逻辑和与redux沟通,并把store中的state以及更改state的方法(dispatch)分发给UI组件,而connect()方法就是起这个作用的。
connect()
const Container = connect(mapStateToProp,mapDispatchToProps)(UI)
这样Container就是一个被加工的容器组件,这传代码的意思是,connect方法接受两个参数:mapStateToProps和mapDispatchToProps。它们定义了 UI 组件的业务逻辑。前者负责输入逻辑,即将state映射到 UI 组件的参数(props),后者负责输出逻辑,即将用户对 UI 组件的操作映射成 Action。
从本质上说connect可以看作是一个高阶函数
mapStateToProps
- mapStateToProps函数返回的是一个对象;
- 返回的对象中的key就作为传递给UI组件props的key,value就作为传递给UI组件props的value
- mapStateToProps用于传递状态
mapDispatchToProps
- mapDispatchToProps函数返回的是一个对象;
- 返回的对象中的key就作为传递给UI组件props的key,value就作为传递给UI组件props的value
- mapDispatchToProps用于传递操作状态的方法
<Provider/>
Provider组件就是基于react中的Context实现的,connect方法生成容器组件以后,需要让容器组件拿到state对象,才能生成 UI 组件的参数。这里用Provider就可以直接让容器组件拿到了。具体源码实现这里就不放了。
代码格式
就看看redux在生产环境中是如何使用的吧,我们做出这样一个效果
上方Count组件可以拿到下方Person组件的人数,然后Person组件也可以取到上方Count组件的求和数,先看项目文件
action
除了redux文件夹里面的东西要讲一讲外其他的都没啥必要了。那就按顺序,我们分析需求,要用到redux,就先把这些文件夹建起来,该装的依赖装好,然后分需求,看看有什么,Count组件要计算, Person组件要添加人数,然后根据这些需求去写action
1 | // constant.js 文件 |
然后就根据action写reducer
1 | /* |
然后联合reducer
1 | /* |
然后创建store
1 | /* |
至此,关于redux的文件就弄好了,接下来就去弄容器组件,Count组件要的state是Count和跟Person人数,Action是数字的运算,则有
1 | export default connect( |
Person类似
1 |
|
至此,对于react的基本介绍就到这里了。