redux-saga

599 阅读1分钟

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);

image.png

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文件的编写

  1. takeEvery:可以传入多个监听的actionType,每一个都可以被执行(对应有一个takeLatest,会取消前面的)

  2. put:在saga中派发action不再是通过dispatch,而是通过put;

  3. 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;