react中间件的thunk和saga区别是什么


本文摘自PHP中文网,作者coldplay.xixi,侵删。

react中间件的thunk和saga区别:1、【redux-thunk】仅支持原始对象【(plain object)】,处理有副作用的action;2、【redux-saga】中处理了所有的异步操作, 异步接口部分一目了然。

本教程操作环境:windows7系统、React17版,该方法适用于所有品牌电脑。

相关学习推荐:react视频教程

react中间件的thunk和saga区别:

1、redux-thunk 的使用与缺点

(1)redux-thunk 的使用

thunk 是 redux 作者给出的中间件, 实现极为简单, 10 多行代码:

1

2

3

4

5

6

7

8

9

10

11

function createThunkMiddleware(extraArgument) {

  return ({ dispatch, getState }) => next => action => {

    if (typeof action === 'function') {

      return action(dispatch, getState, extraArgument);

    }

    return next(action);

  };

}

const thunk = createThunkMiddleware();

thunk.withExtraArgument = createThunkMiddleware;

export default thunk;

这几行代码做的事情也很简单, 判别 action 的类型, 如果 action 是函数, 就调用这个函数, 调用的步骤为:

1

action(dispatch, getState, extraArgument);

发现实参为 dispatch 和 getState, 因此我们在定义 action 为 thunk 函数是, 一般形参为 dispatch 和 getState.

(2)redux-thunk 的缺点

thunk 的缺点也是很明显的, thunk 仅仅做了执行这个函数, 并不在乎函数主体内是什么, 也就是说 thunk 使得 redux 可以接受函数作为 action, 但是函数的内部可以多种多样. 比如下面是一个获取商品列表的异步操作所对应的 action

store 里面先引入中间件

1

2

3

4

5

6

7

8

9

10

11

12

13

import { createStore, applyMiddleware, compose } from 'redux';

import thunk from 'redux-thunk';

import rootReducer from './reducers/index';

const initialState = {};

const middleware = [thunk];

export const store = createStore(

rootReducer,

initialState,

compose(

applyMiddleware(...middleware),

Windows.__REDUX_DEVTOOLS_EXTENSION__ && Windows.__REDUX_DEVTOOLS_EXTENSION__()

)

);

action 文件里

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

import { FETCH_POSTS, NEW_POST } from './type'

export const fetchPosts = () => dispatch => {

fetch("https://jsonplaceholder.typicode.com/posts")

        .then(res => res.JSON())

        .then(posts =>

        dispatch({

        type: FETCH_POSTS,

        payload: posts

        })

        )

}

export const createPost = postData => dispatch => {

fetch("https://jsonplaceholder.typicode.com/posts",{

        method: "POST",

        headers:{

            "content-type":"application/json"

        },

        body:JSON.stringify(postData)

    })

    .then(res => res.JSON())

    .then(post =>

    dispatch({

    type: NEW_POST,

    payload: post

    })

    )

}

从这个具有副作用的 action 中, 我们可以看出, 函数内部极为复杂. 如果需要为每一个异步操作都如此定义一个 action, 显然 action 不易维护.

action 不易维护的原因:

I)action 的形式不统一

II)就是异步操作太为分散, 分散在了各个 action 中

2、redux-saga 的使用

在 redux-saga 中, action 是 plain object(原始对象), 并且集中处理了所有的异步操作, 下面我们以 redux-saga 的官方例子 shopping-cart为例, 来说说 redux-saga 的使用.

shopping-cart例子很简单, 展示的是如下过程:

商品列表 -->添加商品 -->购物车 -->付款

具体的页面, 如下:

显然, 这里有两个明显的异步操作需要执行:

获取商品列表和付款

getAllProducts()checkout()来表示, 如果用 thunk, 那么这两个异步的操作分属于两个不同的 action 中, 但是在 saga 中, 它们是集中处理的.

使用 saga, 我们先生成一个集中处理异步的 saga.JS 文件:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

import { put, takeEvery, call } from 'redux-saga/effects'

import { CHANGE_HITOKOTO_RESP, CHANGE_HITOKOTO } from '../actions/Hitokoto'

import hitokotoApi from '../services/hitokoto'

function gethitokoto() {

    return hitokotoApi.get().then(resp => resp)

}

export function* changeHitokoto() {

    const defaultHitokoto = {

        'id': 234,

        'hitokoto': '没有谁能够永远坚强下去的, 每个人都会有疲累的无法站起的时候. 世间的故事, 就是为了这一刻而存在的哦.',

        'type': 'a',

        'from': '文学少女',

        'creator': '酱七',

        'created_at': '1468605914'

    };

    try {

        const data = yield call(gethitokoto);

        const hitokotoData = JSON.parse(data);

        yield put({ type: CHANGE_HITOKOTO_RESP, hitokotoData });

    } catch (error) {

        yield put({ type: CHANGE_HITOKOTO_RESP, hitokotoData: defaultHitokoto });

    }

}

export default function* shici() {

    yield takeEvery(CHANGE_HITOKOTO, changeHitokoto)

}

抛去其他部分 (具体用法我们待会解释), 我们看到在 saga.JS 中集中了这两个异步操作getAllProducts()checkout()

此外, 在 saga 中的 action 跟原始对象是完全相同的, 我们来看 saga 中的 action creator :

1

2

3

4

5

6

export const GET_ALL_PRODUCTS = 'GET_ALL_PRODUCTS'

export function getAllProducts() {

  return {

    type: GET_ALL_PRODUCTS,

  }

}

上述的 action creator 中, 创建的 action 是一个 plain object, 跟我们在 redux 中同步 action 的样式是统一的.

redux-saga 的优缺点

优点:

(1)集中处理了所有的异步操作, 异步接口部分一目了然

(2)action 是普通对象, 这跟 redux 同步的 action 一模一样

(3)通过 Effect, 方便异步接口的测试

(4)通过 worker 和 watcher 可以实现非阻塞异步调用, 并且同时可以实现非阻塞调用下的事件监听

(5) 异步操作的流程是可以控制的, 可以随时取消相应的异步操作.

缺点: 太复杂, 学习成本较高

相关学习推荐:javascript学习教程

以上就是react中间件的thunk和saga区别是什么的详细内容,更多文章请关注木庄网络博客

相关阅读 >>

React native有什么作用

讨论React axios 跨域访问一个或多个域名问题

没有babel能运行vue与React

React中样式冲突怎么解决

React中图片用什么标签

React中如何引入样式

webpack 不识别React怎么办

安装React脚手架会报错怎么办

React中的refs是什么

React中qs是什么

更多相关阅读请进入《React》频道 >>




打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...