redux 个人整理
序
本人工作之余的闲暇时间还是很充裕的。在完成经理安排的任务后,基本上都是在自学,主要是阅读各种技术文档、浏览博客、运行别人写的一些前端demo并观赏与赞叹。在ScorpionJay 同学的带领下,我们决定决定做一个react版的音乐播放SPA(Single Page web Application)。
首选,模仿网易云的界面,因为是程序猿最爱的音乐播放器,不解释!然而,分析网易云的数据请求时,貌似全是403。github上有大牛提供了网易云音乐的一些接口,非常好。所以,对于数据接口,我们最后选择了“哈喽,酷狗!”。
阅读了redux的文档后,并参与了一个练手项目r-music的部分开发后,通过自己的理解,整理了这篇文档。
初学,所以一定会有不详或者错误的地方。
参考文档
开发这个项目,我参阅的学习文档如下:
- React 入门实例教程:http://www.ruanyifeng.com/blog/2015/03/react
- React Router 使用教程:http://www.ruanyifeng.com/blog/2016/05/react_router.html
- ECMAScript 6 入门:http://es6.ruanyifeng.com/
- redux中文文档:http://www.redux.org.cn/
- Redux 入门教程(三)——React-Redux 的用法:http://www.ruanyifeng.com/blog/2016/09/redux_tutorial_part_three_react-redux.html
- Flex 布局教程——语法篇:http://www.ruanyifeng.com/blog/2015/07/flex-grammar.html
流程图解
通过我自己的理解方式,简单地整理了react、redux、react-redux三者之间的关系图,如下:

通过代码,梳理redux、react-redux
注:下面代码只列出搜索功能的关键部分,源码地址:https://github.com/ScorpionJay/r-music
1. Provider
react-redux提供的Provider组件,可以让容器组件取得state。
src/index.js
import configureStore from './stores'
const store = configureStore()
<Provider store={store}>
<Router history={browserHistory} routes={routers} />
</Provider>
上面代码中,Provider使得Router的所有子组件可以取得state。
import configureStore from './stores'为redux的store,如下:
src/store/index.js
import reducers from '../reducers/index';
export default function(initialState) {
let createStoreWithMiddleware
// 判断环境是否logger
if (process.env.NODE_ENV === 'production') {
createStoreWithMiddleware = applyMiddleware(thunk)(createStore);
}else{
//开发环境在console可以看到整个状态树的实时日志
const logger = createLogger();
createStoreWithMiddleware = applyMiddleware(thunk,logger)(createStore);
}
let store = createStoreWithMiddleware(reducers, initialState);
return store;
};
2. react:Component
src/containers/search.js
import React, { Component, PropTypes } from 'react'
import { connect } from 'react-redux'
import { searchHotAPI,searchResultAPI,clearSearchResultAPI} from '../actions/search'
class Search extends Component {
constructor(props) {
super(props);
}
componentDidMount(){
const { dispatch } = this.props
dispatch(searchHotAPI())
}
searchEvt(keyword,page=1){
const { dispatch } = this.props;
keyword = keyword || this.refs.keyword.value
if(keyword!=''){
dispatch(searchResultAPI(keyword, page));
}else{
dispatch(clearSearchResultAPI());
}
this.refs.keyword.value = keyword;
}
render() {
const { dispatch,controll,search } = this.props;
return (
<div className='root' style={{fontSize:'1.2rem'}}>
//...
</div>
)
}
}
function map(state) {
return {
search: state.search,
controll: state.music.controll
}
}
export default connect(map)(Search)
react-redux的connect方法,用于从 UI 组件生成容器组件。
上面代码中,connect(map)(Search)使得组件Search可以通过props取得map返回的数据。
dispatch(searchHotAPI())和dispatch(clearSearchResultAPI()),获取数据并分发action。
3. redux
src/actions/search.js
import Config from '../config'
import { spin,spinHidden } from './spin'
import api from '../api'
import Storage from '../storage'
//定义常量
export const SEARCH_HOT = 'SEARCH_HOT'
export const SEARCH_RESULT = 'SEARCH_RESULT'
//actionCreator,这里是一个函数,返回action对象
const searchHot = (obj) => {return {type:SEARCH_HOT, obj}}
const searchResult = (obj) => {return {type:SEARCH_RESULT, obj}}
//搜索热门关键字
export function searchHotAPI(){
return async dispatch => {
try{
let hots = await api( Config.searchHotAPI );
dispatch(searchHot(hots.data.info));
} catch(error) {
console.log(error);
}
}
}
//通过关键字搜索
export function searchResultAPI(keyword,page){
return async dispatch => {
try {
let result = await api( Config.searchResultAPI, 'get', {keyword,page} );
//搜索历史存到localStorage
setSearchHistory(keyword);
dispatch(searchResult(result.data.info));
} catch(error) {
console.log(error);
}
}
}
上面代码中,searchHot和searchResult都是Action creator,即分别返回一个action。
action是一个带有type关键字的对象,如{type:SEARCH_HOT, obj}和{type:SEARCH_RESULT, obj}。
searchHotAPI和searchResultAPI分别返回一个获取数据并分发action的异步函数,一般在容器组件里会调用。
src/reducer/search.js
import { combineReducers } from 'redux'
import { SEARCH_HOT,SEARCH_RESULT } from '../actions/search'
function hots(state = [], action){
switch(action.type) {
case SEARCH_HOT:
return action.obj;
default:
return state;
}
}
function result(state = [], action){
switch(action.type) {
case SEARCH_RESULT:
return action.obj;
default:
return state;
}
}
const Reducers = combineReducers({
hots,result,
})
export default Reducers
上面代码中,hots函数收到名为SEARCH_HOT的 Action 以后,就返回一个新的 State,作为热门搜索的结果。
在src/store/index.js中,开发环境下,引入了中间件redux-logger的createLogger,在浏览器console可以观察到每次reducer的结果,如下:

src/reducer/index.js
import { combineReducers } from 'redux'
//...
import search from './search'
const reducers = combineReducers({
//...
search,
})
export default reducers
Reducer 是一个函数,它接受 Action 和当前 State 作为参数,返回一个新的 State,然后View发生变化。 combineReducers将多个拆分的reducer合并。
redux 个人整理的更多相关文章
- Redux----Regular的Redux实现整理
Regular的Redux实现整理 什么问题? 组件的树形结构决定了数据的流向,导致的数据传递黑洞 怎么解决? 所有组件都通过中介者传递共享数据 方案: 中介者: (function create ...
- 【原】整理的react相关的一些学习地址,包括 react-router、redux、webpack、flux
因为平时经常去网上找react相关的一些地址,找来找去很麻烦,所以自己整理了一下,不过前面部分不是我整理的, 是出自于:http://www.cnblogs.com/aaronjs/p/4333925 ...
- react与redux学习资料的整理
**重点内容**React学习 1.新手入门可以访问react的官方网站,如果英语不是特别好的同学可以访问中文版的,具体链接http://reactjs.cn/react/index.html 首页有 ...
- React初识整理(五)--Redux和Flux(解决状态传递问题)
Flux 1.引入:在React的应⽤中,状态管理是⼀个⾮常重要的⼯作.我们不会直接对DOM节点进⾏操作,⽽是通过将数据设置给state,由state来同步UI,这种⽅式有个潜在的问题,每个组件都有独 ...
- redux学习
redux学习: 1.应用只有一个store,用于保存整个应用的所有的状态数据信息,即state,一个state对应一个页面的所需信息 注意:他只负责保存state,接收action, 从store. ...
- 我要成为前端工程师!给 JavaScript 新手的建议与学习资源整理
来源于:http://blog.miniasp.com/post/2016/02/02/JavaScript-novice-advice-and-learning-resources.aspx 今年有 ...
- Redux原理(一):Store实现分析
写在前面 写React也有段时间了,一直也是用Redux管理数据流,最近正好有时间分析下源码,一方面希望对Redux有一些理论上的认识:另一方面也学习下框架编程的思维方式. Redux如何管理stat ...
- 微信小程序(应用号)资源汇总整理
微信小应用资源汇总整理 开源项目 WeApp - 微信小程序版的微信 wechat-weapp-redux-todos - 微信小程序集成Redux实现的Todo list wechat-weapp- ...
- Redux教程1:环境搭建,初写Redux
如果将React比喻成士兵的话,你的程序还需要一位将军,去管理士兵(的状态),而Redux恰好是一位好将军,简单高效: 相比起React的学习曲线,Redux的稍微平坦一些:本系列教程,将以" ...
随机推荐
- numpy数学计算
1.求范数 np.linalg.norm norm(x, ord=None, axis=None, keepdims=False) 范数理论的一个小推论告诉我们:ℓ1≥ℓ2≥ℓ∞
- 关于在调用JAVAFX相关包时遇到Access restriction: The type 'Application' is not API (restriction on required library)的解决方法
点击工具栏的Project->Properties->Java Build Path->Libraries-> 双击第一项 点击Add添加允许javafx 然后就不会报错了
- javaweb笔记一
内连接(自然连接): 只有两个表相匹配的行才能在结果集中出现 外连接: 包括 (1)左外连接(左边的表不加限制) (2)右外连接(右边的表不加限制) (3)全外连接(左右两表都不加限制 一个空的构造器 ...
- web文件<async-supported>错误分析
<async-supported>true</async-supported> 出现 cvc-complex-type.2.4.a: Invalid content was f ...
- Oracle学习笔记:parallel并行处理
在使用oracel查询时,可以通过并行提高查询速度.例如: ) from table_name a; 强行启用并行度来执行当前SQL.加上这个说明之后,可以强行启用Oracle的多线程处理功能,提高效 ...
- Python爬虫之HDU提交数据
前一篇http://www.cnblogs.com/liyinggang/p/6094338.html 使用了爬虫爬取hdu 的代码,今天实现了将数据向hdu 提交的功能,接下来就是需要将两个功能合并 ...
- 2016-2017-2 20155309 南皓芯《java程序设计》第八周学习总结
教材学习内容总结 本周学习的主要是第十四章,第十五章的内容. NIO与NIO2 同步非阻塞IO(Java NIO) : 同步非阻塞,服务器实现模式为一个请求一个线程,即客户端发送的连接请求都会注册到多 ...
- OA项目CRUD和单元测试(一)
使用ModeFirst方法生成数据库,EntityFramework5.0. 一:Model层的模型:(根据模型生成数据库) 二:Dal层的UserInfo代码: namespace SunOA.EF ...
- nsis安装包_示例脚本语法解析
以下是代码及解析,其中有底色的部分为脚本内容. 注释.!define.变量.!include.常量 ; Script generated by the HM NIS Edit Script Wizar ...
- hdu 5131 (2014广州现场赛 E题)
题意:对给出的好汉按杀敌数从大到小排序,若相等,按字典序排.M个询问,询问名字输出对应的主排名和次排名.(排序之后)主排名是在该名字前比他杀敌数多的人的个数加1,次排名是该名字前和他杀敌数相等的人的个 ...