在react-native中使用redux框架 原

 

在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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章