react-saga (用于中大型项目)用起来是比react-thunk 麻烦很多,但是他的优势可以将代码进行分离, 单独写在saga.js中 ,并没有与actionCreators.js 有太多的耦合度 而且传入dispatch()还是对象 没有违和感
使用过程:
1.安装:
yarn add redux-saga
2.导入创建中间件的函数 createSagaMiddleware
import createSagaMiddleware from 'redux-saga'
3.通过createSagaMiddleware创建中间件
const sagaMiddleware = createSagaMiddleware();
4.应用中间件 并且放到applyMiddleware函数中
// applyMiddleware(中间1,中间2,中间3)
const storeEnhancer = applyMiddleware(thunkMiddleware, sagaMiddleware);
generator
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// function foo(){
// console.log('foo执行了');
// }
// foo();
//生成器函数的定义:
// function *foo() {
// function* foo() {
// // return '123' 不生效
// yield "one";
// yield "tow";
// yield "three";
// }
function* foo() {
// return '123' 不生效
//不调next() 下面的代码是一次都不会执行的
console.log('111');
yield "one";
console.log('222');
yield "tow";
console.log('333');
yield "three";
yield new Promise((res, rej) => {
console.log("hahaha");
});
//要执行下面的代码 就肯定要再次调用next 不需要前面有yield 也可以执行的
console.log('第五次调next: nonono');
}
//返回的是迭代器
const result = foo();
console.log(result);//foo {<suspended>}
// 3.使用迭代器
//调用一次next 就会消耗一次迭代器
const res1 = result.next()
// 执行顺序 也是从上到下调用一次 就到yield停止执行
const res2 = result.next()
const res3 = result.next()
const res4 = result.next()
// const res5 = result.next()
console.log(res1);
console.log(res2);
console.log(res3);
console.log(res4);//hahaha
// console.log(res5);
// { value: "one", done: false } value 是yield 后面的结果
// { value: "tow", done: false }
// { value: "three", done: false }
// {value: undefined, done: true}
function* bar() {
console.log("1212131231");
const result = yield new Promise((resolve, reject) => {
setTimeout(() => {
resolve("Hello world!")
}, 2000)
})
//下面的代码 还没有输出 result
console.log('同步拿到:', result);
}
const it = bar();
// console.log(it);
console.log(
// it.next()//{value: Promise, done: false}
it.next().value.then(res => {
// console.log('异步拿到的:',res);//异步拿到的: Hello world!
//但是我们想要的是同步拿到 result
// res 是等于 Hello world! 但是result 只是定义了 还没有赋值
// it.next();//同步拿到: undefined
// res作为上一次yield的结果
it.next(res);//同步拿到:Hello world!
})
);
</script>
</body>
</html>
saga.js文件的编写
-
takeEvery:可以传入多个监听的actionType,每一个都可以被执行(对应有一个takeLatest,会取消前面的)
-
put:在saga中派发action不再是通过dispatch,而是通过put;
-
all:可以在yield的时候put多个action;
5.调用run(传入生成器函数) 启动中间件的监听过程,并且传入要监听的saga;
sagaMiddleware.run(saga);
6.生成器函数 监听想要监听action对应的type
7.在另一个生成器函数中写自己的代码
import { takeEvery ,put,all} from "redux-saga/effects";
import { FETCH_ABOUT_MULTIDATA } from "./constances";
import axios from "axios";
import { changeBannersAction, changeRecommendsAction } from "./actionCreators";
function* fetchAboutMultidata(action) {
const res = yield axios.get("http://123.207.32.32:8000/home/multidata");
console.log(res);
const banners = res.data.data.banner.list;
const recommends = res.data.data.recommend.list;
// yield put(changeBannersAction(banners));
// yield put(changeRecommendAction(recommends));
yield all([
yield put(changeBannersAction(banners)),//done 如果里面判断done 是false next()会继续执行
yield put(changeRecommendsAction(recommends)),
]);
}
function* mySaga() {
//监听action 的type
// yield takeEvery(FETCH_ABOUT_MULTIDATA,生成器函数)
yield takeEvery(FETCH_ABOUT_MULTIDATA, fetchAboutMultidata);
//内部 已经做完了这不操作
// it.next().value.then(res => {
// it.next(res);
// })
}
// export default 生成器函数
export default mySaga;