React-cli使用Redux以及使用redux-persist处理刷新页面redux中数据丢失的问题

React-cli使用Redux以及使用redux-persist处理刷新页面redux中全局数据丢失的问题

写在前面:项目基于 react + typescript + react-router + antd + redux + redux-persist

React-create-app中使用Redux

首先目录结构如下

| -- src
	| -- pages
		| -- Home
			| -- Home.tsx
		| -- Login
			| -- Login.tsx
    | -- store
        | -- action.js 
        | -- index.js
        | -- reducers.js
        | -- state.js
App.tsx
index.tsx

state.js

// 声明默认值
export default {
    loginState: false    //登录状态
}

reducers.js

// 工具函数,用于组织多个reducer,并返回reducer集合
import {combineReducers} from 'redux'
// 默认值
import defaultState from './state.js'
// 一个reducer就是一个函数
const loginState = (state = defaultState.loginState, action) => {
    // 不同的action有不同的处理逻辑
    switch (action.type) {
        case 'SET_LOGIN_STATE':
            return action.data;
        default:
            return state
    }
};
// 导出所有reducera
export default combineReducers({
    loginState
})

action.js

export function setLoginState(data) {
    console.log('setLoginState',data)
    return (dispatch, getState) => {
        dispatch({ type: 'SET_LOGIN_STATE', data: data })
    }
}

index.js

// applyMiddleware: redux通过该函数来使用中间件  createStore: 用于创建store实例
import {applyMiddleware, createStore} from 'redux'
// 中间件,作用:如果不使用该中间件,当我们dispatch一个action时
// ,需要给dispatch函数传入action对象;但如果我们使用了这个中间件,那么就可以传入一个函数,这个函数接收两个参数:dispatch和getState。这个dispatch可以在将来的异步请求完成后使用,对于异步action很有用
import thunk from 'redux-thunk'
// 引入reducer
import reducers from './reducers.js';
import {persistStore, persistReducer} from 'redux-persist';
//  存储机制,可换成其他机制,当前使用sessionStorage机制
import storageSession from 'redux-persist/lib/storage/session';

const storageConfig = {
    key: 'root', // 必须有的
    storage:storageSession, // 缓存机制
    blacklist: ['name'] // reducer 里不持久化的数据,除此外均为持久化数据
};
const myPersistReducer = persistReducer(storageConfig, reducers);

// 创建store实例
let store = createStore(
    myPersistReducer,
    applyMiddleware(thunk)
);
export const persistor = persistStore(store)
export default store

****使用

Login.tsx

import React from "react";
import "./Login.less";
import {setCookie} from "../../utils/utils";
import {Form, Input, Button, Checkbox} from 'antd';
import { connect } from 'react-redux';
// 引入action
import { setLoginState } from "../../store/action"

class Login extends React.Component<any, any> {
    constructor(props: any) {
        super(props);
        this.state = {
            layout: {
                labelCol: {span: 8}, wrapperCol: {span: 16},
            },
            tailLayout: {
                wrapperCol: {offset: 8, span: 16},
            },
            user:{
                account:"",password:""
            }
        }
    }
    onFinish = (values: any) => {
        console.log('Success:', values,this.state.user);
        const {user} = this.state;
        const {history,setLoginState}=this.props;
        /**
         * TODO 存cookie 修改redux中的登陆状态
         * **/
        setCookie('token','1asas');
        setCookie('account',user.account);
        setLoginState(true);
        history.push("/")
    };
    onFinishFailed = (values: any) => {
        console.log('Failed:', values);
    };
    //input的value值改变
    valueChange(name:any,e:any){
        let d = Object.assign({},this.state.user);
        d[name] = e.target.value;
        this.setState({user:d});
    };
    render(): React.ReactElement<any, string | React.JSXElementConstructor<any>> | string | number | {} | React.ReactNodeArray | React.ReactPortal | boolean | null | undefined {
        let {layout, tailLayout,user } = this.state;
        return (
            <div className={"bg"}>
                <div className="LoginBox">
                    <div className="left">
                        <img src={require("../../assets/images/logo.png")} alt=""/>
                    </div>
                    <div className="right">
                        <Form {...layout} name="basic" className={'forms'}
                              initialValues={{remember: true}}
                              onFinish={this.onFinish.bind(this)}
                              onFinishFailed={this.onFinishFailed.bind(this)}
                        >
                            <Form.Item label="账号" name="username" rules={[{required: true, message: '请输入账号!'}]}>
                                <Input value={user.account} onChange={this.valueChange.bind(this,'account')}/>
                            </Form.Item>

                            <Form.Item label="密码" name="password" rules={[{required: true, message: '请输入密码!'}]}>
                                <Input.Password  value={user.password} onChange={this.valueChange.bind(this,'password')}/>
                            </Form.Item>

                            <Form.Item {...tailLayout} name="remember" valuePropName="checked">
                                <Checkbox>Remember me</Checkbox>
                            </Form.Item>

                            <Form.Item {...tailLayout}>
                                <Button type="primary" htmlType="submit"> 登录 </Button>
                                <span className={"forget"}>忘记密码</span>
                            </Form.Item>
                        </Form>
                    </div>
                </div>

            </div>
        );
    }
}
// mapStateToProps:将state映射到组件的props中
const mapStateToProps = (state:any) => {
    return {
        loginState: state.loginState
    }
}
// mapDispatchToProps:将dispatch映射到组件的props中
const mapDispatchToProps = (dispatch:any, ownProps:any) => {
    return {
        setLoginState (data:any) {
            // 如果不懂这里的逻辑可查看前面对redux-thunk的介绍
            dispatch(setLoginState(data))
        }
    }
}
export default connect(mapStateToProps, mapDispatchToProps)(Login);

redux-persist处理刷新页面redux中全局数据丢失的问题

在react项目中 通过redux react-redux 管理全局数据 但是使用redux就会有一个问题 如果用户刷新了页面,那么原本存储在redux中的全局数据就会被重置

一般情况下可以通过session 或者localstorage实现数据存储的要求,但是既然使用的redux,在使用本地存储就不太高级了,这个时候就需要使用redux-persist来进行数据存储,【从原理上来说,还是将某些数据存储在本地,所以直接使用session localstorage也是可以的】

修改 index.js

// applyMiddleware: redux通过该函数来使用中间件  createStore: 用于创建store实例
import {applyMiddleware, createStore} from 'redux'
// 中间件,作用:如果不使用该中间件,当我们dispatch一个action时
// ,需要给dispatch函数传入action对象;但如果我们使用了这个中间件,那么就可以传入一个函数,这个函数接收两个参数:dispatch和getState。这个dispatch可以在将来的异步请求完成后使用,对于异步action很有用
import thunk from 'redux-thunk'
// 引入reducer
import reducers from './reducers.js';
import {persistStore, persistReducer} from 'redux-persist';
//  存储机制,可换成其他机制,当前使用sessionStorage机制
import storageSession from 'redux-persist/lib/storage/session';

const storageConfig = {
    key: 'root', // 必须有的
    storage:storageSession, // 缓存机制
    blacklist: ['name'] // reducer 里不持久化的数据,除此外均为持久化数据
};
const myPersistReducer = persistReducer(storageConfig, reducers);

// 创建store实例
let store = createStore(
    myPersistReducer,
    // reducers,
    applyMiddleware(thunk)
);
export const persistor = persistStore(store)
export default store

修改入口文件 index.tsx

import React from 'react';
import ReactDOM from 'react-dom';
import './index.less';
import App from './App';
import Login  from "./pages/Login/Login";
import Detail from "./pages/Detail/Detail";
import * as serviceWorker from './serviceWorker';
import {BrowserRouter, Route, Switch} from 'react-router-dom';
// @ts-ignore
import { Provider } from 'react-redux';
import {PersistGate} from 'redux-persist/lib/integration/react';
import store from './store/index.js'
import {persistor} from './store';
//路由
const Routes = () => {
    return (
    <Provider store={store}>
        <BrowserRouter>
            <PersistGate loading={null} persistor={persistor}>
            {/*<React.StrictMode>*/}
                <Switch>
                    <Route path='/Login' component={Login}/>
                    <Route path='/Detail' component={Detail}/>
                    <Route path='/' component={App}/>
                </Switch>
            {/*</React.StrictMode>*/}
            </PersistGate>
        </BrowserRouter>
        {/* 将store作为prop传入,即可使应用中的所有组件使用store */}
    </Provider>
)
};

ReactDOM.render(Routes(), document.getElementById('root'));
serviceWorker.unregister();

接下来打开浏览器调试工具,查看浏览器的缓存,就可以看到缓存的数据。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值