关于React redux概念性的东西可以阅读Redux中文文档和阮一峰老师的redux入门教程,但是实践出真知,所以上手才是最重要的,下面就是基于redux的实现,请看截图:http://blog.csdn.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('登陆错误~');
-
- });
- }
- }
这里我是用的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;
- }
至此就大功告成了!