在react-native中使用redux框架

原创
2017/03/31 13:22
阅读数 2.4K

 

在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({},state,{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;

 

3.store
store是action和reducer的粘合剂,它可以完成以下任务:
  1. 保存整个程序的state
  2. 通过getState()方法访问state的值
  3. 通过dispatch()方法执行一个action
  4. 通过subscribe(listener)注册回调,监听state的变化

 例如:

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

展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部