继续前面一篇的话题,開始学习react,redux。
react:
1、概括来说。它就是将页面进行组件化,这样就能够对这些组件进行复用。
(中文学习网址: http://reactjs.cn/react/docs/tutorial.html )
2、JSX:在react中会出现以JSX结尾的文件。这样的文件里是 React 独有的 JSX 语法,跟 JavaScript 不兼容。我们能够理解为用JSX结尾的文件里。能够直接使用html来进行编码就能够了。
redux: 用它自己的话说:Redux 是 JavaScript 状态容器,提供可预測化的状态管理(http://camsong.github.io/redux-in-chinese/index.html)。
它不但和能够和react来配合使用。也能和其它的界面库进行配合使用。当前已有的react-redux,就是react和redux的桥梁。
3、首先记住一个图:react和redux的工作图(从网上copy的):
1)这里的组件,我们先简单的理解为我们使用react来实现的可视化的某个button或者图标。用户第一眼看到的就是组件和组件上展示的数据,这个数据的值就存在state中。如今我们先假设这个组件是一个button,上面有文字。
2)action:动作,能够理解为组件能够响应的动作。比方说这个button能够点击。那么这个action就须要定义一个点击的动作。
3)reducer:能够理解为应对action这个动作。将state中的数据进行改动的行为。state是不能够直接进行改动的。必须通过触发action,然后reducer再依据action将数据更新进state中。
4)state:这个东西就是纯纯的数据了,它通过组件进行展现。
当reducer进行更新state之后,组件会自己主动更新展示的数据。
以下我们来举个栗子,用来具体说明这些东西。
可能会写到哪说到哪。没怎么写博客,请见谅。
图例如以下。就是一个加法的button(bootstrap我们先无论,理解先再说) :
先看下总的文件文件夹:
├── actions 这里包括的文件,都是actions的集合
│ ├── ActionCounter.jsx
│ ├── ActionCounter1.jsx
│ └── HomeActions.js
├── components 这里的文件。都是组件
│ ├── ComponentsCounter.js
│ ├── ComponentsCounter1.js
│ └── Home.js
├── constants 这里的文件,都是将actions的操作类型统一定义
│ └── ActionTypes.js
├── containers 将app的入口设置在这里。能够注冊多个组件
│ ├── App.js
│ ├── hello.jsx
│ └── stock.jsx
├── index.js 入口js
├── reducers action中定义的动作,在这里都有相应的改变state的函数
│ ├── ReducersCounter.js
│ ├── ReducersCounter1.js
│ ├── Sample.js
│ └── index.js
├── store 设置state的初始化
│ └── configureStore.js
└── utils 一些杂类。包括中间件
├── devTools.js
└── logMiddleWare.js
依照上面的文件夹结构,同一时候结合工作图,開始开发那么一个简单的东西。
1、定义一个action,该action就是相应组件求和button的动作的。
GET_SUM : 这样的定义应该统一放在一个文件。
return的内容。这个返回一个action,当中type是必须的,填为该action的类型,其它是自定义的,不提倡写入太多的数据。
当中action的书写规范地址: https://github.com/acdlite/flux-standard-action
2、定义一个组件,该组件就是一个表单。
就包括三个输入框和一个点击button,当点击的时候就得出和。
submitHandler :用以响应点击事件。调用action的方法能够如图中所看到的,选择当中一种。
export default connect(state => state.Counter)(Counter); 这一句比較关键,指的是,使用reducer中的Counter来对action事件进行响应。
3、定义一个reducer,用以给action来填充数据,在reducer中不应该做除了填充数据之外的其它动作。
假设后面再出现减法。能够直接在这个函数中对类型进行区分然后进行操作。
4、最后将组建注冊到app中:
须要注意的是: Provider 中仅仅能包括一个组件。假设有多个组建,须要多个组件一起,如:
另一点关于store的,就是在整个project中。这个是唯一的。假设有多个reducer,那么事实上也是用combineReducers函数,将这些reducer整合在一起。形成一个相似树一样的数据结构:
5、关于store文件夹,这里的代码比較少。可是包括了中间件的内容。
applyMiddleware函数: 该函数能够将中间件组合到流程图中来。没有使用该函数时,其数据流例如以下:
组件=>action=>reducers=>state=>组件。
state就是我们程序中自行给我们维护的数据。假设我们想在这个数据流中插入一个功能,比方想进行每次reducers运行之前,打印一下state的内容。也就是说数据流要变成这样: 组件=>action=>其它=>其它…..=>reducers=>state=>组件,假设不使用applyMiddleware是不可能的。例如以下我们写一个打印日志的中间件:
const returnValue = next(action);
这一行的returnValue是不论什么中间件都必须返回的。表示让 applyMiddleware运行完本中间件之后。下一个应该运行的action是哪个。
6、关于thunkMiddleware,这个函数解释起来比較拗口,在官网上说它是异步action。事实上就本菜理解,跟异步相关的都要么涉及多线程或者至少来个IO复用啥的。因此对它迷惑了好久。事实上能够全然无论它叫什么。仅仅要简单的理解为,事实上他就提供了一个为延迟再决定调用哪个action的解决方式。我们再在刚刚的栗子上改改来看。把刚才的加和变成那么一个屌丝的东西,用以确认其所说的所谓异步究竟是个什么鬼,同一时候也能够顺便看看内部的state的状态变化:
该button点击之后。接受后台返回的json数据。随便挑一个字段来进行展示,变成以下这个:
1)既然要跟后台服务进行交互。我就随便抄了个后面服务的样例,返回一个jison数据(当然在实际应用中这个数据的或者不应该那么简单的,临时先无论): {id:100,name:”chenyinjing”},后台服务样例:
先将其跑起来。
2)再改动原本的action中的定义。由于有网络交互我们须要定义三个操作的类型。一个用以展示在组件上让用户知道当前在进行交互,一个用以在网络响应失败的时候应该提示用户的数据,另一个用以定义网络成功后的须要进行的action.
这里会发现定义了四个函数,那么刚刚说了。仅仅须要三个action剩下的那个是什么鬼?这个事实上就是之前说的。用以提供延迟调用action的函数的入口。首先先运行POSTS_REQUEST动作,使得当前组件展示眼下正在请求后台中。然后再使用fetch进行HTTP请求。最后将返回的json数据返回给展示组件。在这里没有进行异常检測。
3)组件的实现就比較简单了。再抄抄:
4)最后我们运行一下。看下state的状态变化:
预计许多人和我一样有疑惑。就是action里面定义的返回的数据中,和reducer返回的数据之间的关系。看这里,预计大家都明确了,action中定义的是,组件的动作会产生哪些数据,而reducer返回的数据返回的是。这个action进行一系列操作之后,可能会产生一些数据结果。而这些结果就是reducer数据定义返回的。
7、关于redux-router:原本想看看这里的。可是由于官方的版本号这里变化很频繁,所以就没有看。想着后面点看看能不能出个稳定版。
最后。关于redux写完了,都是很easy东西,希望大神路过。后面会继续学习关于bootstrap的东西才行。