《React-Native系列》24、 结合Demo学习Redux框架
2016-08-31 23:06
761 查看
8月的最后一天了,那就打响最后一炮吧!
我们介绍了Flux框架,我们打算在接下来的项目里使用Redux框架,这两天简单学习了下Redux。打算结合一个Demo来讲解。
还是先来说说概念吧。
整个应用的 state 被储存在一棵 object tree 中,并且这个 object tree 只存在于唯一一个 store 中。
这让同构应用开发变得非常容易。来自服务端的 state 可以在无需编写更多代码的情况下被序列化并注入到客户端中。由于是单一的 state tree ,调试也变得非常容易。在开发中,你可以把应用的 state 保存在本地,从而加快开发速度。此外,受益于单一的 state tree ,以前难以实现的如“撤销/重做”这类功能也变得轻而易举。
State 是只读的
惟一改变 state 的方法就是触发 action,action 是一个用于描述已发生事件的普通对象。
这样确保了视图和网络请求都不能直接修改 state,相反它们只能表达想要修改的意图。因为所有的修改都被集中化处理,且严格按照一个接一个的顺序执行,因此不用担心 race condition 的出现。 Action 就是普通对象而已,因此它们可以被日志打印、序列化、储存、后期调试或测试时回放出来。
使用纯函数来执行修改
为了描述 action 如何改变 state tree ,你需要编写 reducers。
我们再来介绍下Redux中有三个基本概念,Action,Reducer,Store。
代码如下:
1、修改传入参数;
2、执行有副作用的操作,如 API 请求和路由跳转;
3、调用非纯函数,如 Date.now() 或 Math.random()。
我们定义了2个reduce (reduceNum.js reduceText.js)
reduceNum如下:
reduceText如下:
我们使用combineReducers 合并reduce
关于combineReducers 参考http://cn.redux.js.org/docs/api/combineReducers.html
维持应用的 state;
提供 getState() 方法获取 state;
提供 dispatch(action) 方法更新 state;
通过 subscribe(listener) 注册监听器;
通过 subscribe(listener) 返回的函数注销监听器。
再次强调一下 Redux 应用只有一个单一的 store。当需要拆分数据处理逻辑时,你应该使用 reducer 组合 而不是创建多个 store。
根据已有的 reducer 来创建 store 是非常容易的。我们使用 combineReducers() 将多个 reducer 合并成为一个。现在我们将其导入,并传递 createStore()。
好了,概念就介绍到这儿,贴下Demo的源码。
入口组件:
视图组件:AddTodo
Demo运行的效果如下:
代码结构目录如下:
写在后面的话:
Redux真不是一两句话可以说清楚的,这里提供了一个简单的完整Demo,希望可以帮助到大家。
参考:http://cn.redux.js.org/index.html
我们介绍了Flux框架,我们打算在接下来的项目里使用Redux框架,这两天简单学习了下Redux。打算结合一个Demo来讲解。
还是先来说说概念吧。
Redux 三个基本原则
单一数据源整个应用的 state 被储存在一棵 object tree 中,并且这个 object tree 只存在于唯一一个 store 中。
这让同构应用开发变得非常容易。来自服务端的 state 可以在无需编写更多代码的情况下被序列化并注入到客户端中。由于是单一的 state tree ,调试也变得非常容易。在开发中,你可以把应用的 state 保存在本地,从而加快开发速度。此外,受益于单一的 state tree ,以前难以实现的如“撤销/重做”这类功能也变得轻而易举。
State 是只读的
惟一改变 state 的方法就是触发 action,action 是一个用于描述已发生事件的普通对象。
这样确保了视图和网络请求都不能直接修改 state,相反它们只能表达想要修改的意图。因为所有的修改都被集中化处理,且严格按照一个接一个的顺序执行,因此不用担心 race condition 的出现。 Action 就是普通对象而已,因此它们可以被日志打印、序列化、储存、后期调试或测试时回放出来。
使用纯函数来执行修改
为了描述 action 如何改变 state tree ,你需要编写 reducers。
我们再来介绍下Redux中有三个基本概念,Action,Reducer,Store。
Action
Action 本质上是 JavaScript 普通对象。我们约定,action 内必须使用一个字符串类型的 type 字段来表示将要执行的动作。多数情况下,type 会被定义成字符串常量。当应用规模越来越大时,建议使用单独的模块或文件来存放 action。代码如下:
export const addTodo = (num) => { return { type: 'INCREMENT', num: num, } } export const decTodo = (num) => { return { type: 'DECREMENT', num: num, } } export const updateText = (text) => { return { type: 'TEXT_UPDATE', text: text, } }
Reducer
reducer 就是一个纯函数,接收旧的 state 和 action,返回新的 state。(previousState, action) => newState保持 reducer 纯净非常重要。永远不要在 reducer 里做这些操作:
1、修改传入参数;
2、执行有副作用的操作,如 API 请求和路由跳转;
3、调用非纯函数,如 Date.now() 或 Math.random()。
我们定义了2个reduce (reduceNum.js reduceText.js)
reduceNum如下:
const todo = (state=0, action) => { switch (action.type) { case 'INCREMENT': return state + 1 case 'DECREMENT': return state - 1 default: return state//返回原来的state } } export default todo
reduceText如下:
const todo = (state="", action) => { switch (action.type) { case 'TEXT_UPDATE': //新的state return action.text default: //返回原来的state return state } } export default todo
我们使用combineReducers 合并reduce
import { combineReducers } from 'redux' import reduceNum from './reduceNum' import reduceText from './reduceText' const todoApp = combineReducers({ num:reduceNum, text:reduceText }) export default todoApp
关于combineReducers 参考http://cn.redux.js.org/docs/api/combineReducers.html
Store
Store 就是把action和reduce联系到一起的对象。Store 有以下职责:维持应用的 state;
提供 getState() 方法获取 state;
提供 dispatch(action) 方法更新 state;
通过 subscribe(listener) 注册监听器;
通过 subscribe(listener) 返回的函数注销监听器。
再次强调一下 Redux 应用只有一个单一的 store。当需要拆分数据处理逻辑时,你应该使用 reducer 组合 而不是创建多个 store。
根据已有的 reducer 来创建 store 是非常容易的。我们使用 combineReducers() 将多个 reducer 合并成为一个。现在我们将其导入,并传递 createStore()。
import reducers from './reducers' import { createStore } from 'redux' let initState = { num: 0,text:""}; let store = createStore(reducers,initState);createStore() 的第二个参数是可选的, 用于设置 state 初始状态。
好了,概念就介绍到这儿,贴下Demo的源码。
入口组件:
/** * Sample React Native App * https://github.com/facebook/react-native * @flow */ import React, { Component } from 'react'; import { AppRegistry, StyleSheet, Text, View } from 'react-native'; import { createStore } from 'redux' import { Provider } from 'react-redux' import reducers from './reducers' import AddTodo from './containers/AddTodo' class reduxdemo extends Component { render() { // let initState = { num: 0,text:""}; let store = createStore(reducers); return ( <Provider store={store}> <AddTodo /> </Provider> ) } } AppRegistry.registerComponent('reduxdemo', () => reduxdemo);
视图组件:AddTodo
import React,{Component} from 'react' import { AppRegistry, StyleSheet, Text, View, TouchableHighlight, Dimensions, } from 'react-native'; import { connect,Provider } from 'react-redux' import { addTodo,decTodo,updateText } from '../actions' const {width, height} = Dimensions.get('window'); class AddTodo extends Component { constructor(props) { super(props); } render() { const { dispatch,num ,text} = this.props // alert(num); return ( <View style={styles.container}> <TouchableHighlight style={styles.itemView} underlayColor="red" onPress={()=>{dispatch(addTodo(num))}}> <Text style={styles.itemText}> 点击我就+1 </Text> </TouchableHighlight> <TouchableHighlight style={styles.itemView} underlayColor="red" onPress={()=>{dispatch(decTodo(num))}}> <Text style={styles.itemText}> 点击我就-1 </Text> </TouchableHighlight> <TouchableHighlight style={styles.itemView} underlayColor="red" onPress={()=>{dispatch(updateText('测试'))}}> <Text style={styles.itemText}> 修改Text的值 </Text> </TouchableHighlight> <Text style={{paddingTop:10,color:'red'}}> 当前的Num值是:{num} , 当前的Text值是:{text} </Text> </View> ) } } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#f2f2f2', marginTop:20, }, itemView:{ backgroundColor:'grey', height:44, width:width, justifyContent:'center', marginTop:10, }, itemText:{ fontSize:15, color:'#ffffff', textAlign:'left', marginLeft:20, }, }); //selector:这是你自己编写的一个函数。这个函数声明了你的组件需要整个 store 中的哪一部分数据作为自己的 props。 function selector(state) { return { num: state.num , text:state.text } } // 包装 component ,注入 dispatch 和 state 到其默认的 connect(selector)(App) 中; export default connect(selector)(AddTodo);
Demo运行的效果如下:
代码结构目录如下:
写在后面的话:
Redux真不是一两句话可以说清楚的,这里提供了一个简单的完整Demo,希望可以帮助到大家。
参考:http://cn.redux.js.org/index.html
相关文章推荐
- React-Native 学习系列课程笔记(React-Native开发环境搭建)
- 《React-Native系列》24、 结合Demo学习Redux框架
- 一步一步学习 ReactNative + Redux(4:中间件)
- React-Native学习笔记——react-redux最佳实践应用篇
- React-Native 学习系列课程笔记(React-Native 开发从零开始)
- 一步一步学习 ReactNative + Redux(1)
- 一步一步学习 ReactNative + Redux(5:异步Action)
- 一步一步学习 ReactNative + Redux(3)
- React-Native学习笔记——react-redux最佳实践基础篇
- RN学习系列---Windows下安装搭建React-Native环境
- ReactNative之ListView学习总结(二)带有section的demo
- 《React-Native系列》27、 Redux的异步数据流
- 一步一步学习 ReactNative + Redux(6)
- Android React-Native系列之<二>零基础学习React-Native控件之View
- 《React-Native系列》 RN学习之NodeJS
- React-Native学习笔记之:使用Tab react-native-tab-navigator框架
- React-Native学习笔记之:弹框框架Popover简单使用
- React Native Redux TodoList Demo
- [5]Selenium学习系列----Sikuli图形识别框架和Selenium结合