首先目录结构如下
| -- src
| -- pages
| -- Home
| -- Home.tsx
| -- Login
| -- Login.tsx
| -- store
| -- action.js
| -- index.js
| -- reducers.js
| -- state.js
App.tsx
index.tsx
// 声明默认值
export default {
loginState: false //登录状态
}
// 工具函数,用于组织多个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
})
export function setLoginState(data) {
console.log('setLoginState',data)
return (dispatch, getState) => {
dispatch({ type: 'SET_LOGIN_STATE', data: data })
}
}
// 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
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);
在react项目中 通过redux react-redux 管理全局数据 但是使用redux就会有一个问题 如果用户刷新了页面,那么原本存储在redux中的全局数据就会被重置
一般情况下可以通过session 或者localstorage实现数据存储的要求,但是既然使用的redux,在使用本地存储就不太高级了,这个时候就需要使用redux-persist来进行数据存储,【从原理上来说,还是将某些数据存储在本地,所以直接使用session localstorage也是可以的】
// 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
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}>
{/**/ }
<Switch>
<Route path='/Login' component={Login}/>
<Route path='/Detail' component={Detail}/>
<Route path='/' component={App}/>
</Switch>
{/**/}
</PersistGate>
</BrowserRouter>
{/* 将store作为prop传入,即可使应用中的所有组件使用store */}
</Provider>
)
};
ReactDOM.render(Routes(), document.getElementById('root'));
serviceWorker.unregister();
接下来打开浏览器调试工具,查看浏览器的缓存,就可以看到缓存的数据。