6、谷粒后台使用redux管理数据
环境准备
安装插件
yarn add redux react-redux redux-thunk redux-devtools-extension在入口
index.js文件中包装/** * 入口文件 */ import React from 'react'; // 引入redux import { Provider } from 'react-redux' import ReactDOM from 'react-dom'; import memoryUtils from './utils/memoryUtils' import storageUtils from './utils/storageUtils' import App from './App'; import store from './redux/store' const user = storageUtils.getUser() memoryUtils.user = user ReactDOM.render( // 包装 (<Provider store={store}><App /></Provider>), document.getElementById('root') );在
src目录下创建redux文件,分别创建如下文件action-type.js/** * 包含n个action的type常量标识名称的模块 */actions.js/** * 包含n个action creator函数的模块 * 同步:对象{} * 异步:thunk */reducer.js/** * 用来根据老的state和指定的action生成并返回新的state的函数 */ import storageUtils from '../utils/storageUtils' import { combineReducers } from 'redux' const initHeadTitle = '' // 用来管理头部标题的reducer function headTitle (state = initHeadTitle, action) { switch (action.type) { default: return state } } // 用来管理用户的reducer const initUser = storageUtils.getUser() function User (state = initUser, action) { switch (action.type) { default: return state } } // 向外默认暴露的是合并产生的总的reducer函数 // 管理的总的结构: /** { headTitle:'首页', user:{} } */ export default combineReducers({ headTitle, User })store.js/** * redux核心管理对象 */ // 向外默认暴露store import { createStore, applyMiddleware } from 'redux' import thunk from 'redux-thunk' import { composeWithDevTools } from 'redux-devtools-extension' import reducer from './reducer' export default createStore(reducer, composeWithDevTools(applyMiddleware(thunk)))
头部标题
显示
此时已经在redux中存储了值,只需要包装ui组件,使其获取到redux中的值即可。
编辑
header.jsx// 1. 引入组件 import { connect } from 'react-redux' // 2. 包装暴露对象 export default connect( (state) => ({ headTitle: state.headTitle }), {} )(withRouter(Header)) // 3. 修改获取title的方法 const title = this.props.headTitle
修改
修改标题发生在点击左侧菜单栏之后。因此逻辑大概是当点击某个菜单后重新设置redux中的值。
编辑
action-type.js文件,新增一个标识export const SET_HEAD_TITLE = 'set_head_title'编辑
actions.js文件,定义一个设置头部标题的actionimport { SET_HEAD_TITLE } from './action-type' // 设置头部标题的同步action export const setHeadTitle = (headTitle) => ({ type: SET_HEAD_TITLE, data: headTitle })更新
reducer.jsimport { SET_HEAD_TITLE } from './action-type' // 用来管理头部标题的reducer function headTitle (state = initHeadTitle, action) { switch (action.type) { case SET_HEAD_TITLE: return action.data default: return state } }修改
left-nav.jsx文件// 1. 引入插件 import { connect } from 'react-redux' // 2. 引入设置标题的actions(函数) import { setHeadTitle } from '../../redux/actions' // 为点击绑定事件 if (this.hasAuth(item)) { if (!item.children) { // 当前要显示的item if (item.key === path || path.indexOf(item.key) === 0) { // 设置点击事件 this.props.setHeadTitle(item.title) } // 向pre中添加 pre.push( <Menu.Item key={item.key}> <IconFont type={item.icon} /> <Link to={item.key} // 设置点击事件 onClick={() => this.props.setHeadTitle(item.title)} > {item.title} </Link> </Menu.Item> ) } } // 4. 封装暴露对象 export default connect((state) => ({}), { setHeadTitle })(withRouter(LeftNav))
用户信息
定义
actions-type// 接收用户信息 export const RECEIVE_USER = 'receive_user' // 显示错误信息 export const SHOW_ERROR_MSG = 'show_error_msg'定义
actionsimport { SET_HEAD_TITLE, RECEIVE_USER, SHOW_ERROR_MSG } from './action-type' import { reqLogin } from '../api' import storageUtils from '../utils/storageUtils' // 接收用户的同步action export const recevieUser = (user) => ({ type: RECEIVE_USER, user }) // 显示错误信息的同步action export const showErrorMsg = (errorMsg) => ({ type: SHOW_ERROR_MSG, errorMsg }) // 登录的异步action export const login = (username, password) => { return async dispath => { // 1. 执行异步ajax请求 const result = await reqLogin(username, password) if (result.status === 0) { // 2.1 成功=>分发 成功的同步action const user = result.data // 保存到local中 storageUtils.saveUser(user) // 分发接收用户的同步action dispath(recevieUser(user)) } else { // 2.2 失败=>分发 失败的同步action const msg = result.msg // message.error(msg) dispath(showErrorMsg(msg)) } } }为
reducer增加新的处理方式import { SET_HEAD_TITLE, RECEIVE_USER, SHOW_ERROR_MSG } from './action-type' function user (state = initUser, action) { switch (action.type) { case RECEIVE_USER: console.log(action.user); return action.user case SHOW_ERROR_MSG: const errorMsg = action.errorMsg return { ...state, errorMsg } default: return state } }在
login.jsx组件中使用// 1. 引入 import { connect } from 'react-redux' import { login } from '../../redux/actions' // 2. 包装 export default connect((state) => ({ user: state.user }), { login })(Login) // 3. 使用 (this.props.user)
退出
actions.js// 退出登录同步 export const logout = () => { // 删除local中的user storageUtils.removeUser() return { type: RESET_USER } }reducer.jsfunction user (state = initUser, action) { switch (action.type) { case RECEIVE_USER: console.log(action.user); return action.user case SHOW_ERROR_MSG: const errorMsg = action.errorMsg return { ...state, errorMsg } case RESET_USER: return {} default: return state } }
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 小康博客!
评论
TwikooDisqusjs









