# redux 封装
redux 到底要解决什么问题?管理被多个组件所依赖或者影响的状态;
一个action需要被多个reducer处理吗?
## 构建
```
$ yarn build
```
## 关于redux
actions可以被各个页面组件和reducers复用
- 各个页面(组件)如果挂载到路由,export出`mapStateToProps`,系统就会将`LayoutComponent`组件或默认导出组件 与redux关联,即可使用`this.props.actions`中的方法,获取到redux中的数据;
- 各个页面(组件)如果不是挂载到路由上的,需要显示调用`connectComponent`或者`connect`装饰器与redux的连接;
- 各个页面(组件)如果已经与redux进行连接,通过`const {actions} = this.props`获取actions对象,然后调用`actions.xxx()` 触发action;
- `mapStateToProps` 用于指定redux的state中哪部分数据用于当前组件,由于reducer的`combineReducers`方法包装之后,将各个reducer的state存放在对应的key中,key指的是combineReducers包装时指定的key,比如:
```javascript
export default combineReducers({
home, // 这个home就是key,es6写法
utils,
});
// src/layout/home.js
export function mapStateToProps(state) {
return {
...state.home, // 这个home指的就是 combineReducers中的key
...state.app // 如果使用 ... home和app中如果有同名属性,app会覆盖home,可以通过调整...state.app,和...state.home得顺序,决定当前页面使用谁的属性。
};
}
```
- action负责准备数据,数据来源:
- 调用action方法时传入的参数
- ajax请求的异步数据
- storage/cookie中获取数据
- reducer为纯函数,负责处理数据,要对state做deepcopy,返回一个新的数据,不要直接操作state,不会涉及异步,不操作Storage,单纯的获取action的数据之后,做进一步处理。
- store负责将数据以props形式传递给component,以及通过中间件对数据统一处理。
- 组件,调用触发action,获取store处理过的数据,不发送ajax,不操作storage,单纯的展示数据。
- 适当的区分哪些数据需要redux处理,哪些数据直接使用state,不要为了redux而redux
- 哪些数据适合使用redux处理?
- 异步数据(包括ajax,websocket,异步状态loading等)
- 来自cookie/localStorage等其他存储的数据
- 多组件公用数据
- 多组件间通信数据
- 哪些数据直接使用组件内部state即可?
- 不涉及组件外数据修改(比如ajax修改后端数据),不被其他任何外部组件使用的数据,比如:点击显示隐藏modal;点击展开收起div等控制内部状态的数据。
### action:
- action 使用的是`redux-actions`模块构建的 `Flux Standard Action`
```javascript
createAction(type, payloadCreator = Identity ? metaCreator )
```
- 各个action文件之间,不允许出现同名方法,`src/actions/index.js`中有检测。
### 回调处理
调用actions方法时,给actions方法传入一个回调参数,这个回调参数,最终是由 `createAction` 的 `metaCreator` 参数处理的,项目中做了封装。`metaCreator` 可以携带业务以外的数据,异步actions会触发两次reducer,第一次触发时`payloadCreator` 传递给reducer的是promise对象,无法携带其他数据了,这时候就可以通过`metaCreator`携带额外的数据。
```javascript
export const testAsync = createAction(
types.TEXT_ASYNC_DEMO,
async()=> {
return await homeService.getMsg(); // 返回promise
},
(onResolve, onReject)=> {
return {
onResolve,
onReject,
sync: 'home'
}
}
);
/* 解释
(onResolve, onReject)=> {
return {
onResolve,
onReject,
sync: 'home'
}
}
就是 createAction 的第三个参数 metaCreator,是一个函数,这个函数返回的数据,最终存放在action的meta中。
返回数据 onResolve 和 onReject 就是调用action方法时传入的回调函数,一个代表成功,一个代表失败,这两个数据最终会被 src/store/asyncActionCallbackMiddleware.js中间件使用
*/
```
### 异步写法
异步是使用`src/store/promise-middleware.js`中间件进行处理的
一本异步action其实是触发了两次reducer,第一次标记异步开始,reducer可以获取相应的标记,第二次异步完成,返回数据。具体可以参考`promise-middleware.js`源码
#### action异步写法
```javascript
import {createAction} from 'redux-actions';
import * as types from '../constants/actionTypes';
import * as profileService from '../services/profile-service';
export const saveUserMessage = createAction(types.SAVE_USER_MESSAGE,
(userMessage) => profileService.saveUserMessage(userMessage), // 返回一个promise实例
(userMessage, onResolve, onReject) => {
// 异步action将触发reducer两次,reducer第一次触发获取payload是promise对象,额外的数据就要metaCreator提供了。
return {
onResolve, // 执行异步action成功回调,使页面可以获取异步成功
onReject, // 执行异步action失败回调,使页面可以处理异步失败
errorTip: '保存失败', // 系统自动提示错误, 默认 ‘未知系统错误’ 传递false,不使用系统提示
successTip: '个人信息修改成功', // 默认 false,不显示成功提示信息,
};
}
);
```
#### reducer 异步写法:
有两种写法,第一种有机会获取所有action的数据,第二种,只能获取自己type的action数据,个人觉得获取所有action数据没有用,反而状态受干扰。推荐第二种写法
```javascript
import * as types from '../constants/actionTypes';
let initialState = {
isSidebarCollapsed: false,
fetching: false,
};
export default function (state = initialState, action) {
const {payload, error, meta={}, type} = action;
const {sequence = {}} = meta;
const status = sequence.type === 'start';
if (status || error) { // 出错,或者正在请求中,注意: 这种写法将捕获所有异步action,自己模块得status要在自己的case中写。
return {
...state,
fetching: status,
};
}
switch (type) {
case types.TOGGLE_SIDE_BAR: {
const isSidebarCollapsed = !state.isSidebarCollapsed;
return {
...state,
isSidebarCollapsed,
};
}
case types.GET_STATE_TO_STORAGE: {
return {
...state,
...(payload.setting || initialState),
};
}
default:
return state;
}
}
```
```javascript
import {handleActions} from 'redux-actions';
import * as types from '../constants/actionTypes';
let initialState = {
loading: false,
orderState: '',
};
export default handleActions({
[types.SAVE_USER_MESSAGE](state, action) {
const {error, meta = {}} = action;
const {sequence = {}} = meta;
const loading = sequence.type === 'start';
// loading 要反应到页面上,
// error由middleware处理,全局message提示,或者各个页面添加回调处理
if (loading || error) {
return {
...state,
loading,
};
}
return {
...state,
orderState: 'success',
loading,
};
},
}, initialState);
```
### redux中的异常处理
- 基于`flux-standard-action` 规范,异常action返回结构为:`{..., payload: error, error: true, ...}`
- `utils-middleware.js`会统一截获处理异常(无论异步还是同步), 会根据 `meta.errorTip`来确定是否全局提示处理异常信息
- `async-action-callback-middleware.js` 会调用actions的回调函数,给具体页面处理异常
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
收起资源包目录
毕业设计:基于Python + React 开发的在线文档管理系统.zip (381个子文件)
mobile.css 1KB
index.css 1KB
style.css 1KB
App.css 564B
.gitignore 890B
index.html 2KB
test.html 992B
favicon.ico 4KB
avatar.jpeg 32KB
login-bg.jpg 122KB
epub_cover1.jpg 39KB
webpack.config.js 35KB
webpack.config.bak.js 35KB
index.js 17KB
tree.js 15KB
BasicLayout.js 9KB
index.js 9KB
configHoc.js 8KB
webpackDevServer.config.js 7KB
menus.js 7KB
build.js 7KB
system.js 7KB
userAuth.js 6KB
routeLoader.js 5KB
validationRule.js 5KB
start.js 5KB
c_doc.js 4KB
storage.js 4KB
env.js 4KB
doc.js 4KB
index.js 4KB
modules.js 3KB
menu.js 3KB
index.js 3KB
request.js 3KB
middleware-sync-reducer-to-local-storage.js 3KB
index.js 3KB
user.js 2KB
utils.js 2KB
paths.js 2KB
md5.js 2KB
handle-async-reducer.js 2KB
info.js 2KB
file.js 2KB
handleError.js 2KB
getHttpsConfig.js 2KB
FrontLayout.js 2KB
index.js 2KB
middleware-promise.js 2KB
theme.js 2KB
index.js 2KB
connect.js 1KB
test.js 1KB
fileTransform.js 1KB
email_code.js 1KB
settings.js 1KB
index.js 1KB
action_log.js 1KB
index.js 1KB
reg_code.js 1KB
regexp.js 1KB
announcement.js 946B
team_group.js 916B
sys_set.js 915B
routes.js 876B
page.js 835B
settings.js 752B
PageRoutes.js 744B
queryHoc.js 733B
action-utils.js 699B
side.js 657B
middleware-utils.js 629B
index.js 625B
pnpTs.js 620B
middleware-async-action-callback.js 616B
index.js 588B
check-action.js 555B
App.js 533B
models.js 532B
handleSuccess.js 494B
reportWebVitals.js 362B
cssTransform.js 314B
tagRender.js 284B
action-types.js 282B
setupTests.js 241B
connect-hoc.js 191B
statistics.js 188B
warning.js 183B
package-lock.json 754KB
package.json 7KB
manifest.json 492B
index.jsx 23KB
index.jsx 18KB
index.jsx 18KB
EditModal.jsx 16KB
index.jsx 16KB
index.jsx 15KB
validation.jsx 15KB
index.jsx 14KB
index.jsx 14KB
共 381 条
- 1
- 2
- 3
- 4
资源评论
学术菜鸟小晨
- 粉丝: 1w+
- 资源: 4953
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功