React Native 使用Redux全局共享state

本文介绍了如何在React Native项目中利用Redux实现全局共享状态管理,包括用户登录、信息修改和退出登录的流程。通过创建Reducer、Action和Store,结合react-navigation,实现了组件间状态的共享和修改。同时,提到了ActionTypeConf、User.js、index.js、UserAction.js等关键文件的创建和使用,以及与API交互的部分。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一直想将项目中使用的redux,写成一篇博客,但是又碍于对Redux的掌握能力有限,只能在项目完结的时候,稍稍整理一下redux在项目中全局获取 用户的信息,从用户登录,到修改用户信息,和退出登录全局使用Redux进行保存用户信息,修改用户信息,清空用户信息,一套小小的入门代码。
项目中redux基于react-navigation,可做到:

  1. 某个组件的状态,需要全局共享
  2. 某个状态需要在任何地方都可以拿到
  3. 一个组件需要改变全局状态
  4. 一个组件需要改变另一个组件的状态

由于项目篇幅涉及的可能会比较多,简单的一些操作,这里不做教程

1、我们要npm一下redux的相关组件
redux、react-redux 、redux-actions、redux-thunk
2、当然不能少了 react-navigation

1、项目中iOS和android,我们注册导出的根组件为Root

import {
    AppRegistry,
} from 'react-native';
import Root from './shop/Root';

AppRegistry.registerComponent('ReactNative', () => Root);

2、在Root.js中

import {AppStack} from './Router' // 路由栈(使用react-navigation封装出来的路由栈)
import {Provider} from 'react-redux';
import configureStore from './redux/Store'
const store = configureStore({});

export default class Root extends Component {
    render() {
        return (
            <Provider store={store}>
                <AppStack />
            </Provider>
        );
    }
}

3、此时我们创建一个redux文件夹,里面包含Reducer,Action,Store

Store 就是保存数据的地方,你可以把它看成一个容器。整个应用只能有一个 Store。
Action 是一个对象
Reducer 是一个函数,它接受 Action 和当前 State 作为参数,返回一个新的 State。

文件夹如下图:
这里写图片描述

4、我们先创建一个ActionTypeConf.js

// 用户信息
export const USER_INFO_GET_LOCAL = 'USER_INFO_GET_LOCAL';  // 获取本地用户信息
export const EDIT_USER = 'EDIT_USER'; // 编辑用户信息
export const USER_CLEAR = 'USER_CLEAR'; // 清空用户信息

5、创建User.js

import * as types from "../ActionTypeConf";

const initialState = {
    user: {},
    token:null
};

export default (state = initialState, action) => {
    switch (action.type) {
        case types.USER_INFO_GET_LOCAL:  // 获取本地的个人信息
            return Object.assign({}, state, {
                user: action.user,
                token: action.token
            });
        case types.EDIT_USER:  // 编辑个人信息
            let tempObj = {};
            Object.assign(tempObj, state, {
                user: action.user,
            });
            return tempObj

        case types.USER_CLEAR: // 清除个人信息
            return initialState;

        default:
            return state;
    }

6、在reduxcers中创建index.js文件,导出相应的user

import { combineReducers } from "redux";
import user from "./User";

//全局状态树根节点key定义
const rootReducer = combineReducers({
    user,
});

export default rootReducer;

7、在action.js中创建UserAction.js文件

import * as types from '../ActionTypeConf';

export function loadUserInfo() {  // 网络请求用户信息
    return dispatch => {
        Api.getLocalUserInfo().then((user) => { 
            Api.getLocalToken().then((token) => {
                if (user && token) {
                    Config.LoginToken=token;
                    dispatch({
                        type: types.USER_INFO_GET_LOCAL,
                        user, token
                    })
                }
            }).catch((err)=>{});

        }).catch((err)=>{});
    };
}

export function cleanUserState() {  // 清除个人信息
    return dispatch=> {
        Api.clearLocalUserInfo().then((data) => {
            dispatch({
                type: types.USER_CLEAR
            })
        }).catch((err) =>{})
    }
}

export function editUser(oldUser, param, callBack) { // 编辑个人信息

    return dispatch=> {
        Api.modifyUserInfo(param).then((data) => {
            let user = {};
            Object.assign(user, oldUser, param);
            Api.setLocalUserInfo(user).then((data) => {
                dispatch({
                    type: types.EDIT_USER,
                    user
                })
            }).catch((err)=>{})

            callBack && callBack();

        }).catch((err) =>{})
    }
}

8、新建Store.js

import {DeviceEventEmitter} from 'react-native';
import {createStore, applyMiddleware} from 'redux';
import thunk from 'redux-thunk';
import rootReducer from './reducers/index';

export default function configureStore(initialState) {

    const store = createStore(
        rootReducer,
        initialState,
        applyMiddleware(thunk), //applyMiddleware方法中传入需要使用的中间件
    );

    store.subscribe(() => {
        DeviceEventEmitter.emit(Config.EVENT_GLOBAL_STATE_CHANGE, {})
    });
    global.AppReduxStore=store;

    return store;
}

9、登录, 模块导出需要绑定组件

import * as UserAction from '../../redux/actions/UserAction';
import {bindActionCreators} from 'redux';
import {connect} from 'react-redux';


class UserLogin extends React.Component { // 这里不能使用export导出

    // 登录
    Api.userLogin({userCode: this.state.phoneText, userPassword: this.state.passwordText}).then((data) => {
            this.props.userAction.loadUserInfo(); // 登录成功后加载action数据
            // this.dispatch(resetAction);
            this.goBack();
        }).catch(e => {
        });

}

//绑定状态,state  变成this.props
function mapStateToProps(state, ownProps) {
    return {
        getUser: state.user.user
    };
}

//绑定actions
function mapDispatchToProps(dispatch) {
    return {
        userAction: bindActionCreators(UserAction, dispatch),
    };
}

export default connect(
    mapStateToProps,
    mapDispatchToProps
)(UserLogin)

10、api中用户登录,保存本地用户信息,清除本地用户数据,获取本地用户信息等相应接口处理


     /**
     * 保存本地用户信息
     */
    static saveLocalUserInfo(user) {

        return StorageUtil.saveJsonObject(KEY_LOCAL_USER_INFO, user);
    }

    /**
     * 获取本地用户信息
     */
    static getLocalUserInfo() {
        return StorageUtil.getJsonObject(KEY_LOCAL_USER_INFO).then(data => {
            return data;
        });
    }

    /**
     * 清除本地用户信息
     */
    static async clearLocalUserInfo() {
        await StorageUtil.remove(KEY_LOCAL_USER_INFO);
        return true
    }

    /**
     * 登陆
     * @param params
     * @returns {Promise}null
     */
    static userLogin(params = {userCode: '', verifyCode: ''}) {
        return callApi(url, params, {
            method: NetUtil.POST, showLoading: true, resultCallBack: async (result) => {
                if (result && result.data && result.data.auth) {
               await this.userObtainInfo();  //登录完成获取用户信息
                }
                return true;
            }
        });
    }
    /**
     * 网络请求用户信息
     */
    static userObtainInfo() {
        let url = Config.HOST_TRADE_CORE + '/api/v1/yundt/trade/member/detail/get';
        return callApi(url, {}, {
            method: NetUtil.GET, showLoading: true, resultCallBack: async(result) => {
                if (result && result.data) {
                  this.saveLocalUserInfo(result.data)
                }
                return true;
            }
        });
    }

11、在个人中心页面获取绑定的redux保存到本地的值

import * as UserAction from '../../redux/actions/UserAction';
import {bindActionCreators} from 'redux';
import {connect} from 'react-redux';


class Mine extends React.Component { // 这里不能使用export导出
    componentWillMount() {
        Console.log(this.props.getUser) //打印本地存储的网络请求下来的数据
    }
    render() {
        const {realName, mobile, menberId} = this.props.getUser;
        return (
            <View style={styles.container}>
                <Text>{realName}</Text>
            </View>
        );
    }

}

//绑定状态,state  变成this.props
function mapStateToProps(state, ownProps) {
    return {
        getUser: state.user.user
    };
}

//绑定actions
function mapDispatchToProps(dispatch) {
    return {
        userAction: bindActionCreators(UserAction, dispatch),
    };
}

export default connect(
    mapStateToProps,
    mapDispatchToProps
)(Mine)

12、编辑用户信息

// 因为编辑个人信息可能包含用户名,手机号码之类的,所以这里在redux统一处理,只要外界把要修改的字段传入。 
this.props.userAction.editUser(this.props.getUser, {realName: this.state.nameText}, () => {
     Toast.show('修改成功', {  // 提示修改成功
      duration: Toast.durations.SHORT,
      position: Toast.positions.BOTTOM,
      shadow: true,
      animation: true,
      hideOnPress: true,
      delay: 0,
      backgroundColor: '#000000'
      })
      ,this.goBack()})

13、退出登录

 this.props.userAction.cleanUserState();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值