redux——redux-saga常用指令

一、为什么要使用reudx-saga?

在解决redux副作用的中间件中,redux-thunkredux-promise虽然也能解决问题,但是它们会导致action和action创建函数不再纯净,因为它们改动了action,action而redux-saga就是为了解决这个问题,他保持了action和action创建函数的纯净。
同时,redux-saga不仅仅能处理redux副作用的,它还有其它很多功能,延迟、监听等等。

二、安装

npm install --save redux-saga
// 或
yarn add redux-saga

三、使用

启动一个saga任务:

export function* sagaTask() {
  console.log("saga启动了");
}
import { createStore, applyMiddleware } from "redux";
import reducer from "./reducer";
import logger from "redux-logger";
import createSagaMiddleware from "redux-saga";
import { sagaTask } from "./saga";

const sagaMid = createSagaMiddleware();

const store = createStore(reducer, applyMiddleware(sagaMid, logger));

sagaMid.run(sagaTask);

saga指令:

  • take:监听action的触发
    在saga任务中通过take监听类型为SETLOGIN的action
import { take } from "redux-saga/effects";
import { SETLOGIN } from "../action/login";
export function* sagaTask() {
  const action = yield take(SETLOGIN);
  console.log("action", action);
}

当action触发的时候,saga会收到监听执行任务

import { createStore, applyMiddleware } from "redux";
import * as loginActions from "./action/login";
import reducer from "./reducer";
import createSagaMiddleware from "redux-saga";
import { sagaTask } from "./saga";

const sagaMid = createSagaMiddleware();

const store = createStore(reducer, applyMiddleware(sagaMid));

sagaMid.run(sagaTask);

store.dispatch(loginActions.createSetLoginAction(1234)); // 触发action

在这里插入图片描述
注意点:
当saga的生成器函数运行完成时,则saga中间件一定会结束,也就是后面再调用也没有效果,例如:

import { createStore, applyMiddleware } from "redux";
import * as loginActions from "./action/login";
import reducer from "./reducer";
import createSagaMiddleware from "redux-saga";
import { sagaTask } from "./saga";

const sagaMid = createSagaMiddleware();

const store = createStore(reducer, applyMiddleware(sagaMid));

sagaMid.run(sagaTask);

window.setLogin = function () {
  store.dispatch(loginActions.createSetLoginAction(1234));
};

在这里插入图片描述
第一次执行saga监听到了,打印出了action,但是监听完成后saga运行结束,所以后面第二次触发action没有打印出action,因为这时候saga中间件已经结束了

  • all:传入一个数组,数组中存放生成器,saga会等所有的生成器完成之后才会进一步处理
import { all } from "redux-saga/effects";
function* task1() {
  console.log("任务1");
}
function* task2() {
  console.log("任务2");
}
export function* sagaTask() {
  yield all([task1(), task2()]);
  console.log("任务完成");
}

在这里插入图片描述

  • takeEvery:不断的监听某一个action,takeEvery永远不会结束当前的生成器,且它不会阻塞函数的运行
import { takeEvery } from "redux-saga/effects";
import { SETLOGIN } from "../action/login";

function* task() {
  console.log("action执行");
}
export function* sagaTask() {
  yield takeEvery(SETLOGIN, task);
  console.log("监听开始");
}

在这里插入图片描述
在这里插入图片描述

运行后不用触发action直接打印出监听开始,所以说它是不会阻塞函数运行的,且它不会结束当前的生成器,能一直监听action的执行
take也能达到takeEvery同样的效果:

import { take } from "redux-saga/effects";
import { SETLOGIN } from "../action/login";

function* task() {
  console.log("action执行");
}
export function* sagaTask() {
  while (true) {
    yield take(SETLOGIN, task);
    console.log("监听开始");
  }
}

只要不让生成器函数结束,它就能一直监听

  • delay:阻塞指定的毫秒数
import { takeEvery, delay } from "redux-saga/effects";
import { SETLOGIN } from "../action/login";

function* task() {
  yield delay(2000);
  console.log("action执行");
}
export function* sagaTask() {
  yield takeEvery(SETLOGIN, task);
  console.log("监听开始");
}

在这里插入图片描述
浏览器会在2000毫秒后才会输出action执行

  • put:用于重新触发action,相当于dispatch一个action
import { takeEvery, delay, put } from "redux-saga/effects";
import { SETLOGIN, createPutTestAction } from "../action/login";

function* task() {
  yield delay(2000);
  yield put(createPutTestAction(1234));
  console.log("action执行");
}
export function* sagaTask() {
  yield takeEvery(SETLOGIN, task);
  console.log("监听开始");
}

在这里插入图片描述

  • call:用于副作用函数的调用
import { takeEvery, delay, call } from "redux-saga/effects";
import { SETLOGIN } from "../action/login";

function asyncFunc() {
  setTimeout(() => {
    console.log("执行了异步函数");
  }, 3000);
}

function* task() {
  yield delay(2000);
  yield call(asyncFunc);
  console.log("action执行");
}
export function* sagaTask() {
  yield takeEvery(SETLOGIN, task);
  console.log("监听开始");
}

在这里插入图片描述

  • apply:apply的作用和call是一样,只有传入的参数不一样,第一个参数传入的是this的指向,第二个参数传入调用的函数,第三个是传入函数的参数,apply为一个数组,call为字符串
import { takeEvery, delay, apply } from "redux-saga/effects";
import { SETLOGIN } from "../action/login";

function asyncFunc() {
  setTimeout(() => {
    console.log("执行了异步函数");
  }, 3000);
}

function* task() {
  yield delay(2000);
  yield apply(null, asyncFunc);
  console.log("action执行");
}
export function* sagaTask() {
  yield takeEvery(SETLOGIN, task);
  console.log("监听开始");
}

和上面call的例子效果一样

  • select:查询整个仓库当前的状态
import { takeEvery, select } from "redux-saga/effects";
import { SETLOGIN } from "../action/login";

function* task() {
  const state = yield select();
  console.log(state);
}
export function* sagaTask() {
  yield takeEvery(SETLOGIN, task);
  console.log("监听开始");
}

在这里插入图片描述

  • cps:用于调用传统回调方式的异步
import { takeEvery, cps } from "redux-saga/effects";
import { SETLOGIN } from "../action/login";

function cpsFunc(callBack) {
  setTimeout(() => {
    callBack(null, {
      a: 1,
    });
  }, 3000);
}

function* task() {
  const c = yield cps(cpsFunc);
  console.log(c);
}
export function* sagaTask() {
  yield takeEvery(SETLOGIN, task);
  console.log("监听开始");
}

在这里插入图片描述
注意:回调函数的第一个值是返回错误信息

更多指令:https://redux-saga-in-chinese.js.org/docs/api/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值