关于React redux概念性的东西可以阅读Redux中文文档和阮一峰老师的redux入门教程,但是实践出真知,所以上手才是最重要的,下面就是基于redux的实现,请看截图:http://blog.****.net/sinat_17775997/article/details/70861065

分两块描述,先说登陆,登陆的时候,我们需要拿到登陆信息,也就是token,然后在获取购物车相关信息的时候带上token去请求数据,
购物车,我们需要实时的改变购物车的数量,使得下方购物车数量显示正确,当然上面的截图只是拿到了数量,但是没显示到下方的导航栏上,自己加上即可,比较简单
先分析需求,登陆时调接口,拿到token值,加载图相应显示与隐藏,登陆成功跳转到首页(其他页面一样),保存token值
在login.js文件中,当用户点击登陆时走对应的方法,我这里拟定是buttonRegisterOrLoginAction方法,下面截图:
-
import {performLoginAction} from '../../actions/LoginAction'
-
//用户登录/注册
-
buttonRegisterOrLoginAction(position) {
-
const {navigator, dispatch} = this.props;
-
if (position === 0) {
-
//用户登录
-
if (username === '') {
-
toastShort('用户名不能为空~');
-
return;
-
}
-
if (password === '') {
-
toastShort('密码不能为空~');
-
return;
-
}
-
//调用登陆接口,获取token,并保持状态
-
dispatch(performLoginAction(username, password));
-
} else if (position === 1) {
-
//用户注册
-
}
-
}
判断完不能为空,从props中拿到dispatch,分发到相应的action,并把参数传入,在action里面,我们做网络请求以及逻辑处理,
-
export function performLoginAction(username, password) {
-
return (dispatch) => {
-
dispatch(performLogin());
-
fetch(HOST+LOGIN+'?username='+username + '&password='+password)
-
.then((response) => response.json())//取数据
-
.then((responsetext) => {
-
if (responsetext.result === 1) {
-
//登录成功..
-
toastShort('登陆成功~');
-
dispatch(receiveLoginResult(responsetext))
-
-
} else {
-
dispatch(errorLogin())
-
toastShort(responsetext.msg);
-
}
-
}).catch((error) => {
-
toastShort('登陆错误~');
-
//toastLong(error)
-
});
-
}
-
}
这里我是用的get请求,将参数拼接到url里面,当开始登陆,分发相应的action,并根据返回的result判断是否登陆成功,下面是表明3种状态的方法:
-
//登陆失败
-
function errorLogin() {
-
return {
-
type: types.ERROR_LOGIN_ACTION, //自己定义的常量,已区分不同action
-
}
-
}
-
//开始登陆
-
function performLogin() {
-
return {
-
type: types.PERFORM_LOGIN_ACTION,
-
}
-
}
-
//登陆成功
-
function receiveLoginResult(result) {
-
return {
-
type: types.RECEIVE_LOGIN_ACTION,
-
data: result.data
-
}
根据不同的结果分发不同的type和data给reducer处理
在loginReducer里面是对不同store的处理:
-
const initialState = {
-
isLogin:false,
-
loading : false,
-
data:[],
-
status:null
-
}
-
-
export default function login(state = initialState, action){
-
switch (action.type) {
-
case types.PERFORM_LOGIN_ACTION: //开始登陆
-
return {
-
...state,
-
state:'doing',
-
loading: true,
-
isLogin:false
-
};
-
case types.ERROR_LOGIN_ACTION: //登陆失败
-
return {
-
...state,
-
state:null,
-
loading: false,
-
isLogin:false
-
};
-
case types.RECEIVE_LOGIN_ACTION: //完成登陆
-
return {
-
...state,
-
state:'done',
-
loading: false,
-
data: action.data,
-
isLogin:true
-
};
-
default:
-
return state;
-
}
-
}
首先初始化各种属性,然后根据action.type来判断不同的事件,给相应的属性赋值,当开始登陆的时候,加载图开始显示,登陆失败或者登陆完成加载图隐藏,登陆成功,获得返回的数据,并且把isLogin变为true,
在 reducer.js里面把loginReducer加到里面
-
import {combineReducers} from 'redux';
-
import login from './LoginReducer';
-
import goods from './GoodsReducer';
-
-
const rootReducer = combineReducers({
-
login,
-
goods
-
})
-
export default rootReducer;
最后在login.js里面,render里,做相应的操作,使加载图正确显示
- render() {
- let {login} = this.props;
- console.log(login)
- return (
- <View >
- //相应的布局
- <Loading visible={login.loading}/>
- </View>
这里获取的属性里面的login 要用let,不要用const ,因为我们的加载图需要多次修改状态,
在componentDidUpdate方法里面,我们做相应的跳转操作,单词不要打错,否则很尴尬,这个方法是当组件接受到新的属性和状态改变调用,切绘制完毕,这点很重要,否则我们的加载图会转个不停,具体的组件生命周期在这里,react native组件的生命周期
在compomentDidUpdate里是跳转到主页面,由于chrome一直崩溃,就不发这段代码了,最后在login.js下面还需要这个方法:
- function mapStateToProps(state) {
- const {login} = state;
- return {
- login
-
- }
- }
- export default connect(mapStateToProps)(Login);
将我们store里面存储的login和Login.js绑定,以便我们方便的获得更改后的数据
至此登陆的逻辑差不多就走通了,购物车的逻辑和登陆的大部分相似,可以自己看代码理解,大部分都有注释,比较好理解,
最后是app的入口,在不同的系统上运行会跑相应系统的,js文件,所以在里面统一处理,统一入口,
如在index.Android.js文件中:
import React, {Component} from 'react';
import {
AppRegistry,
} from 'react-native';
import root from './App/root';
AppRegistry.registerComponent('Demo', () => root);
统一交由root.js处理,在index.ios.js文件中做相同的操作
在入口组件root.js,把redux导入
-
mport React, { Component } from 'react';
-
import {
-
} from 'react-native';
-
import {Provider} from 'react-redux'
-
import configureStore from './store/configstore'
-
const store=configureStore();
-
import App from './app'
-
import Guide from './guide'
-
export default class rootApp extends Component {
-
render() {
-
return (
-
<Provider store={store} >
-
<App/>
-
</Provider>
-
);
-
}
-
}
并配置我们的store,并使用redux-thunk作为middlewares,这里使用了redux-persist将store保存到本地,方便保存登陆信息
-
import{createStore,applyMiddleware}from 'redux'
-
import thunk from 'redux-thunk'
-
import {persistStore,autoRehydrate} from 'redux-persist' //将store保存到本地,保存登陆信息
-
import {AsyncStorage} from 'react-native'
-
import rootReducer from'../reducers/index'
-
const logger=store=>next=>action=>{ //logger
-
if(typeof action==='function') console.log('dispatching a function');
-
else console.log('dispatching',action);
-
let result=next(action)
-
console.log('next state',store.getState)
-
return result;
-
-
}
-
let middlewares=[logger,thunk]
-
-
const creatStoreWithMiddleware=applyMiddleware(...middlewares)(createStore);
-
-
// export default function configStore(initiaState) {
-
// const store=creatStoreWithMiddleware(rootReducer,initiaState)
-
// return store;
-
// }
-
export default function configStore(onComplete:()=>void) {
-
const store=autoRehydrate()(creatStoreWithMiddleware)(rootReducer)
-
let opt={
-
storage:AsyncStorage,
-
transform:[]
-
}
-
persistStore(store,opt,onComplete)
-
return store;
-
}
至此就大功告成了!