在react-native开发中关于数据的流向,state的管理及路由解决等问题会随着项目的复杂让人越来越头疼,也让人力不从心。于是React的开发者推出了Flux架构及官方实现,力图解决这些问题。Flux框架其核心思想就是单项数据流,Flux的整个流程为:Action -> Dispatcher -> Store -> View.
当然Flux框架只是一种单向数据流的思想,业界有很多基于Flux的框架,当下最流行的当属Redux。
Redux的三大定律:1.单一数据源。2.state是只读的,改变state的唯一方法就是触发action,action其实就是一个普通的javascript对象。3.使用纯函数执行修改,这里所说的纯函数就是Redux中reducer。
Redux的组成:
1.action
首先要知道action就是一个信息载体,也是一个javascript对象,对象中至少要包括一个动作行为的唯一标示,比如增删改查操作。
比如:
userAction.js
import * as constant from '../constants/CommonConstants'; export function updateData(user){ return { type: constant.UPDATE_DATA,user: user }; } export function requestData(){ return dispatch => { let url = 'https://my.oschina.net/gef'; fetch(url) .then((response) =>{ console.log("response:" + response); return response.text(); }) .then((responseText) => { console.log("responseText:" + responseText); if (responseText) { let user = { 'name' : "葛夫锋",'age' : 18,'job' :'developer' }; dispatch(updateData(user)); } }) .catch((error) => { console.log("error:" + error); }); }; }
我定义了两个action,第一个是更新数据的action,第二个是请求数据的action,第二个action所return的其实是一个函数,其参数为dispatch,然后进行了网络请求,请求成功之后执行了第一个action。
2.reducer
action定义了要执行的操作,但是没有规定action执行之后state如何变化,那么reducer的任务就是定义整个程序的state如何响应。
其实reducer就是一个纯函数,例如:
UserReducer.js
import * as constant from '../constants/CommonConstants' const initState = { flag:1,//1请求中 2请求成功 user: null } export default function addUser(state = initState,action){ switch(action.type){ case constant.LOAD_USER: return Object.assign({},state,{flag : 1}); case constant.UPDATE_DATA: return Object.assign({},{flag : 2,user : action.user}); default: return state; } }
baseReducers.js
import {combineReducers} from 'redux'; import UserReducer from './UserReducer'; const rootReducer = combineReducers({ UserReducer }); export default rootReducer;
例如:
index.ios.js
/** * Sample React Native App * https://github.com/facebook/react-native * @flow */ import { AppRegistry,} from 'react-native'; import React from 'react'; import {applyMiddleware,createStore} from 'redux'; import thunk from 'redux-thunk'; import {Provider} from 'react-redux'; import Root from './app/root'; import rootReducers from './app/reducers/baseReducers'; var store = createStore(rootReducers,applyMiddleware(thunk)); function App(props){ return ( <Provider store = {store}> <Root {...this.props}/> </Provider> ); }; AppRegistry.registerComponent('ReduxDemo',() => App);
root.js
import React from 'react'; import {View,StyleSheet,Text} from 'react-native'; import {connect} from 'react-redux'; import {requestData,updateData2} from './actions/userAction'; class Root extends React.Component{ render(){ let {flag,user} = this.props; //flag let content = null; if(flag == 1){ content = (<Text>加载中</Text>); }else{ content = (<Text>加载成功</Text>); } //user let userView = null; if (user) { userView = (<View style = {style.userView}> <Text>姓名:{user.name}</Text> <Text>年龄:{user.age}</Text> <Text>工作:{user.job}</Text> </View>); } return ( <View style = {style.container}> {content} {userView} </View> ); } componentDidMount(){ let {updateData} = this.props; updateData(); } } const style = StyleSheet.create({ container:{ flex: 1,alignItems: 'center',justifyContent:'center',backgroundColor: '#FF6A6A' },userView:{ marginTop:10 } }); function mapStateToProps(state){ return { flag:state.UserReducer.flag,user:state.UserReducer.user }; } function mapDispatchToProps(dispatch){ return { updateData:function(){ dispatch(requestData()); } }; } export default connect(mapStateToProps,mapDispatchToProps)(Root);
这里用到了react-redux库,用于辅助在React项目中使用Redux,它的API相当简单,包括一个React Component(Provider)和一个高阶方法connect。
这里还用到了一个middleware,叫做redux-thunk。redux-thunk的存在允许 store.dispatch一个函数,也就是action不是一个javascript对象,而可以是一个函数。
以上代码例子组合起来就是一个网络异步加载的小例子,其运行效果如下:
完整代码:
https://github.com/johngef/Redux-Demo
原文链接:https://www.f2er.com/react/304419.html