我是靠谱客的博主 饱满跳跳糖,最近开发中收集的这篇文章主要介绍四. redux 学习进阶---Redux常用中间件redux 学习进阶,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

redux 学习进阶

文章目录

  • redux 学习进阶
    • Redux-thunk
    • 四.Redux常用中间件
      • 4.1 Redux-thunk
        • 4.1.1 Redux-thunk 下载
        • 4.1.2 引入redux-thunk
        • 4.1.3 注册redux-thunk
        • 4.1.4 使用redux-thunk中间件
    • redux-saga
      • 4.2 redux-saga
        • 4.2.1 redux-saga解决的问题
        • 4.2.2 redux-saga 下载
        • 4.2.3 创建redux-saga 中间件
        • 4.2.4 注册redux-saga
        • 4.2.5 使用saga接收action执行异步操作
        • 4.2.6 启动saga
      • redux-saga传参
      • redux-saga拆分合并
    • redux-actions
      • 4.3 redux-actions
        • 4.3.1 redux-actions 解决的问题
        • 4.3.2 redux-actions 下载
        • 4.3.3 创建 Action
        • 4.3.4 创建 Reducer

Redux-thunk

四.Redux常用中间件

4.1 Redux-thunk

4.1.1 Redux-thunk 下载

$	npm install redux-thunk

使用插件就不需要我们去手写中间件了

4.1.2 引入redux-thunk

import thunk from 'redux-thunk';

4.1.3 注册redux-thunk

import thunk from 'redux-thunk';
// 注册中间件
export const store = createStore(RootReducer, applyMiddleware(thunk));

4.1.4 使用redux-thunk中间件

const loadPosts = () => async dispatch =>{
const posts = await axios.get('/api/posts').then(response=>response.data)
dispatch({type:LOAD_POST_SUCCESS, payload:posts })
}

action中调用如下

.storeactionscounter.actions.js

export const addCount_async = (payload)=> (dispatch)=>{
setTimeout(()=>{
// 两秒后派发dispatch ,到reducer 处理
dispatch(addCount(payload))
// 等价于这个
// dispatch({type:INCREMENT, payload })
},2000)
}

redux-saga

https://github.com/dL-hx/react-redux-guide

feat/2.0.0分支

4.2 redux-saga

文档学习:

https://redux-saga-in-chinese.js.org/docs/introduction/BeginnerTutorial.html

API_DOC:

https://redux-saga-in-chinese.js.org/docs/api/

4.2.1 redux-saga解决的问题

redux-saga可以将异步操作从Action Creater文件中抽离出来, 放在一个单独的文件中.

比redux-thunk 更好用,功能类似

4.2.2 redux-saga 下载

$	npm install redux-saga --save

4.2.3 创建redux-saga 中间件

import createSagaMiddleware from 'redux-saga';
const sagaMiddleware = createSagaMiddleware();

sagaMiddleware注册给store

4.2.4 注册redux-saga

createStore(RootReducer, applyMiddleware(sagaMiddleware));

4.2.5 使用saga接收action执行异步操作

https://github.com/dL-hx/react-redux-guide

feat/2.0.0分支

import {takeEvery, put} from 'redux-saga/effects';// 引入两个异步方法
function* load_post(){
const {data} = yield axios.get('/api/posts.json');
// put: 用来触发另外一个action,当异步操作时候,
触发action reducer,保存状态
yield put(load_posts_success(data))
}
// saga:文件中,
要求默认导出一个generater 函数
export default function* postSaga(){
// takeEvery:用来接收action,通过takeEvery方法接收组件触发的action
// 接收到的action类型string,
接收这个action 需要执行的方法
yield takeEvery(LOAD_POSTS, load_posts)
}

4.2.6 启动saga

目的:这样做,所写的saga文件才会被加入到redux的工作流中.

import postSaga from './store/sagas/post.saga';
sagaMiddleware.run(postSaga)

.storeindex.js

import { createStore, applyMiddleware } from "redux";
// import reducer from './reducers/counter.reducer'
// 改为合并后的reducers
import RootReducer from "./reducers/root.reducer";
import createSagaMiddleware from 'redux-saga'
import counterSaga from './sagas/counter.saga';
// 创建sagaMiddleware,创建中间件
const sagaMiddleware = createSagaMiddleware()
// 注册redux-saga
export const store = createStore(RootReducer, applyMiddleware(sagaMiddleware));
// 启动counterSaga, 这样才会加入redux工作流中
sagaMiddleware.run(counterSaga)

.storeactionscounter.actions.js

import { INCREMENT ,DECREMENT , INCREMENT_ASYNC } from "../const/counter.const";
//---------------=> action 对象
export const addCount = (payload)=> ({type:INCREMENT, payload })
...
+ export const addCount_async = ()=> ({type: INCREMENT_ASYNC })

.storesagascounter.saga.js

import { takeEvery, put , delay } from "redux-saga/effects"; // 引入两个异步方法
import { addCount } from "../actions/counter.actions";
import { INCREMENT_ASYNC } from "../const/counter.const";
// takeEvery 接收action
// put 触发action
function* addCount_async_fn(){
// 执行异步操作
// 注意: 在generater函数中,
延迟不能使用setTimeout
// 1. 暂停延迟2s
yield delay(2000)
// 2. put 触发action,更新了reducer
yield put(addCount(10))
}
// saga文件默认要求: 导出一个generater函数
export default function* counterSaga() {
// 接收action
// 参数1:接收类型字符串
// 参数2:异步方法执行的函数.
yield takeEvery(INCREMENT_ASYNC, addCount_async_fn);
}

页面调用


<button onClick={addCount_async}>+ 5 </button>

redux-saga传参

https://github.com/dL-hx/react-redux-guide

feat/2.1.0分支

页面调用

 <button onClick={()=>addCount_async_1(20)}>+ 5 </button>

.storesagascounter.saga.js

export const addCount_async_1 = (payload)=> ({type: INCREMENT_ASYNC, payload })

.storesagascounter.saga.js

...
function* addCount_async_1_fn(action){
yield delay(2000)
// 从形参中, 获取页面层组件,
传递来的参数
//
yield put(addCount(10))
// 再次触发action, 修改state状态
yield put(addCount(action.payload))
}
// saga文件默认要求: 导出一个generater函数
export default function* counterSaga() {
// 接收action
// 参数1:接收类型字符串
yield takeEvery(INCREMENT_ASYNC, addCount_async_1_fn);
}

redux-saga拆分合并

https://github.com/dL-hx/react-redux-guide

feat/2.2.0分支


saga组件拆分

.storesagascounter.saga.js

import { takeEvery, put, delay } from "redux-saga/effects"; // 引入两个异步方法
import { addCount } from "../actions/counter.actions";
import { show } from "../actions/modal.actions";
import { INCREMENT_ASYNC } from "../const/counter.const";
import { SHOW_MODAL_ASYNC } from "../const/modal.const";
// takeEvery 接收action
// put 触发action
function* addCount_async_1_fn(action) {
// 1. 暂停延迟2s
yield delay(2000);
// 2. put 触发action
//
yield put(addCount(10))
yield put(addCount(action.payload));
}
function* show_async_fn(action) {
// 1. 暂停延迟2s
yield delay(2000);
yield put(show());
}
// saga文件默认要求: 导出一个generater函数
export default function* counterSaga() {
// 接收action
// 参数1:接收类型字符串
yield takeEvery(INCREMENT_ASYNC, addCount_async_1_fn);
yield takeEvery(SHOW_MODAL_ASYNC, show_async_fn);
}

// 因为如果不拆分, 这个saga文件就会变得很臃肿, 所以需要拆分

.storesagascounter.saga.js

import { takeEvery, put, delay } from "redux-saga/effects"; // 引入两个异步方法
import { addCount } from "../actions/counter.actions";
import { INCREMENT_ASYNC } from "../const/counter.const";
// takeEvery 接收action
// put 触发action
function* addCount_async_1_fn(action) {
// 执行异步操作
// 注意: 在generater函数中,
延迟不能使用setTimeout
// 1. 暂停延迟2s
yield delay(2000);
// 2. put 触发action
//
yield put(addCount(10))
yield put(addCount(action.payload));
}
// saga文件默认要求: 导出一个generater函数
export default function* counterSaga() {
// 接收action
// 参数1:接收类型字符串
yield takeEvery(INCREMENT_ASYNC, addCount_async_1_fn);
}

.storesagasmodal.saga.js

import { takeEvery, put, delay } from "redux-saga/effects"; // 引入两个异步方法
import { show } from "../actions/modal.actions";
import { SHOW_MODAL_ASYNC } from "../const/modal.const";
// takeEvery 接收action
// put 触发action
function* show_async_fn(action) {
// 1. 暂停延迟2s
yield delay(2000);
yield put(show());
}
// saga文件默认要求: 导出一个generater函数
export default function* modalSaga() {
// 接收action
// 参数1:接收类型字符串
yield takeEvery(SHOW_MODAL_ASYNC, show_async_fn);
}

.storesagasroot.saga.js

组合saga文件

import { all } from "redux-saga/effects"; // 引入all方法
import counterSaga from "./counter.saga";
import modalSaga from "./modal.saga";
// saga文件默认要求: 导出一个generater函数
// 通过all方法导出saga文件
export default function* rootSaga() {
yield all([counterSaga(), modalSaga()]);
}

在修改store/index.js文件

进行注册

import { createStore, applyMiddleware } from "redux";
// import reducer from './reducers/counter.reducer'
// 改为合并后的reducers
import RootReducer from "./reducers/root.reducer";
import createSagaMiddleware from 'redux-saga'
// import counterSaga from './sagas/counter.saga';
import rootSaga from './sagas/root.saga';
// 创建sagaMiddleware,创建中间件
const sagaMiddleware = createSagaMiddleware()
// 注册redux-saga
export const store = createStore(RootReducer, applyMiddleware(sagaMiddleware));
// 启动counterSaga, 这样才会加入redux工作流中
// sagaMiddleware.run(counterSaga)
sagaMiddleware.run(rootSaga)

redux-actions

https://github.com/dL-hx/react-redux-guide

feat/2.3.0分支

redux-actions解决的问题

相关文章:

https://zhuanlan.zhihu.com/p/273569290

4.3 redux-actions

4.3.1 redux-actions 解决的问题

redux流程中大量的样板代码读写很痛苦,

,如action, reducer, const,等

使用redux-actions 可以简化Action和Reducer的处理.

4.3.2 redux-actions 下载

$	npm install redux-actions --save
    1. 用于简化action代码
    1. 用于简化reducer代码

4.3.3 创建 Action

使用了redux-actions 这个函数 actions 就不需要自己去定义了

  1. (之前) 手动定义action_create函数

    export const addCount = (payload)=> ({type:INCREMENT, payload })
    
  2. (现在) 通过 ‘redux-actions’ 自动生成该函数,

    使用时候,不用定义type 常量, redux-action的中间件

import { createAction } from 'redux-actions';
const increment_action = createAction('increment');
const decrement_action = createAction('decrement');

4.3.4 创建 Reducer

redux-actions 简化reducer

简化前

counter.reducer.js

import { INCREMENT, DECREMENT } from "../const/counter.const";
const initialState = {
count: 0,
};
function reducer(state = initialState, actions) {
switch (actions.type) {
case INCREMENT: // 数值 + 1 ,返回一个新对象
return {
...state,
// count: state.count + 1,
count: state.count + actions.payload,
};
case DECREMENT:
return {
...state,
// count: state.count - 1,
count: state.count - actions.payload,
};
default:
return state;
}
}
export default reducer;

简化后

import {handleActions as createReducer } from 'redux-actions';
import { addCount_Action, minusCount_Action } from '../actions/counter.actions';
const initialState = { count: 0 }
const counterReducer = createReducer({
[addCount_Action]:(state, actions)=>({
...state,
// count: state.count + 1,
count: state.count + actions.payload,
}),
[minusCount_Action]:(state, actions)=>({
...state,
// count: state.count - 1,
count: state.count - actions.payload,
})
}, initialState)
export default counterReducer;

.storeactionscounter.actions.js

将简化常量文件的定义, 因为后面将通过addCount_Action,这个方法去定义了

createAction: 自动添加了payload方法

import { createAction } from 'redux-actions';
// import { INCREMENT ,DECREMENT , INCREMENT_ASYNC } from "../const/counter.const";
export const addCount_Action = createAction('increment');
// export const addCount_Action = createAction(INCREMENT);
// export const minusCount_Action = createAction(DECREMENT);
export const minusCount_Action = createAction('decrement');

调用

点击按钮时候, 传递到reducer中自动处理, 从而减少了代码量


<button onClick={()=>addCount_Action(20)}>+ 20</button>
<button onClick={()=>minusCount_Action(5)}>- 5</button>

createAction 给我们创建了变量 action 这样就避免了我们在其他文件到处使用字符串 action。

handleActions 给我们生成了 reducer 丰富了reducer 中处理功能,这就是我在大前端训练营所接触的冰山一角。

上一篇:
三. redux 学习进阶—Redux 中间件
下一篇
五. redux 学习进阶—Redux shopping实战案例

最后

以上就是饱满跳跳糖为你收集整理的四. redux 学习进阶---Redux常用中间件redux 学习进阶的全部内容,希望文章能够帮你解决四. redux 学习进阶---Redux常用中间件redux 学习进阶所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(47)

评论列表共有 0 条评论

立即
投稿
返回
顶部