一、使用流程(只记录代码和简单介绍,具体的只是点可以参照Redux 中文文档、React-Redux 官方 Hooks 文档说明)
src下创建目录(依照自己的习惯,当然尽量按照规范同时便于维护)
1.关于actions
Actions 对象是把数据从应用传到 store 的有效载荷。它是 store 数据的唯一来源。用法是通过 store.dispatch() 把 action 传到 store。每个action约定使用type来判断执行改变state的方向,本质上是对象,传入reducer中使用。
2.关于reducer
reducer是state初始化的地方,同时根据actions改变state,reducer 就是一个函数,接收旧的 state 和 action,返回新的 state
注意:
1.不要修改 state。 使用 Object.assign() 新建了一个副本。不能这样使用 Object.assign(state, { visibilityFilter: action.filter }),因为它会改变第一个参数的值。一定要把第一个参数设置为空对象。也可以使用 ES7 中还在试验阶段的特性 { …state, …newState },参考 对象展开语法。
2.在 default 情况下返回旧的 state。遇到未知的 action 时,一定要返回旧的 state。
3.关于store
action 来描述“发生了什么”, reducers 来根据 action 更新 state ,而store是把他们联系在一起的对象(redux应用只有一个单一的store,当需要拆分处理数据的逻辑时,使用 reducer 组合 而不是创建多个 store)
1.维持应用的state
2.提供 getState() 方法获取state
3.提供 dispatch(action) 方法更新state (dispatch调用reducer函数,reducer函数根据传入的action执行操作·······)
4.通过 subscribe(listener)注册监听器
问题: 在使用时,登录成功之后改变了store中存放的关于判断是否登录的状态,改变之后需要通过判断是否改变为已登录状态,从而保存session登录信息以及权限。但是在页面.js中,调用了dispatch之后立即打印登录状态,此时还是为初始值。最后我选择在store的subscribe中监听登录状态,改变时再做操作。
这样可以达到效果,但是不知道是否有其他方式,这样如果应用等级不断的升级,store里会不会变得很冗余。(待。。。。。。。。。。)
代码块
(根据自己摸索的编写一个简单的登录例子,当然文档都说在构建大型的应用需要构思store的结构组成,来达到合理化和方便维护~~)
第一步(编写action)
只提出了action的type来module化
/* 统一存放action对象 */
const actionsType = {
checkLogin:'CHECKLOGIN',
changeSex:'CHANGESEX'
}
export default actionsType
第二步(编写reducer,这里需要初始化state,使用es6函数形参默认值)
前面提到redux永远只有一个唯一的store,当state树比较复杂时,一般是拆分reducer来完成,所以我把reducer也module化
login_re.js
import aT from '../../actions/actionEntry' //引入action的type
import {getSession} from '../../../tool/sessionTool'
let initState = {
isLogin:getSession('isLogin') || false,
path:'/index',//登录成功跳转path
permissions: getSession('permissions') || ''
}
//在reducer里初始化state的值 传入old state 和 action
const login = (state=initState,action)=>{
//根据传入的action的type来执行对应的操作,同时action中还会有一些附带的值(要改变的state值)new state
switch (action.type) {
case aT.checkLogin:
return Object.assign({},state,{
isLogin:action.isLogin,
permissions:action.permissions
})
default:
return state //在 default 情况下返回旧的 state
}
}
export default login
other_re.js
import aT from '../../actions/actionEntry'
let initState = {
sex:'men'
}
export const otherReducer = (state = initState , action) => {
switch (action) {
case aT.changeSex:
return Object.assign({},state,{
sex:action.sex
})
default:
return state;
}
}
reducer的入口文件,通过redux的combineReducers 方法,将所有的reducer module整合成一个统一的对象(自己理解)
reducerEntry.js
import { combineReducers } from 'redux';
import login_reducer from './modules/login_re'
import {otherReducer} from './modules/other_re'
const allReducers = combineReducers({
login_reducer,
otherReducer
})
export default allReducers //导出整合的对象 在createStore时传入
第三步(创建store的入口js文件)
通过redux的createStore传入整合的reducers创建store对象
import { createStore } from 'redux';
import reducers from './reducers/reducerEntry'
import {setSession} from '../tool/sessionTool'
//reducer注入store中
const store = createStore(reducers)
//store监听
store.subscribe(()=>{
console.log(store.getState())
//监听登录状态改变
if(store.getState().login_reducer.isLogin){
setSession('isLogin',store.getState().login_reducer.isLogin)
setSession('permissions',store.getState().login_reducer.permissions)
}
})
export default store
第四步(react中使用时,需要搭配react-redux,通过react-redux的Provider,将store对象注入react应用)
react项目的入口js文件
main.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import EntryRouter from './router/EntryRouter'
import reportWebVitals from './reportWebVitals';
import { Provider } from 'react-redux';//====================
import store from './store/storeEntry'//==================
ReactDOM.render(
<div id='main_box'>
<Provider store={store}>
<EntryRouter />
</Provider>
</div>,
document.getElementById('root')
);
reportWebVitals();
这样redux就大功告成了,剩下的就是使用了,在函数组件和class组件中使用方式有所不同。
分开记录!!!!!!!!!!!!!!!!!