美文网首页
redux-saga基本用法

redux-saga基本用法

作者: 微志异 | 来源:发表于2020-06-07 13:29 被阅读0次

    React提供更优雅的前端代码书写方式和更优的界面更新机制,redux提供了组件和业务分离的解决方案,saga或thunk基于redux提供异步业务实现方案。


    流程图

    图中的Middleware工作于redux内部,介于action和reducer之间,而saga只是某一种Middleware。

    saga工作于action和reducer之间。如果按照原始的redux工作流程,当组件中产生一个action后会直接触发reducer修改state;而往往实际中,组件中发生的action后,在进入reducer之前需要完成一个异步任务,原生的redux不支持这种操作。

    不过,实现异步操作的整体步骤是很清晰的:action被触发后,首先执行异步任务,待完成后再将这个action交给reducer。说到这里,thunk和saga的达到的效果是一致的,差别在于对action的处理完全不一样。

    thunk采用的是扩展action的方式:使得redux的store能dispatch的内容从普通对象扩展到函数。

    const mapDispatchToProps = dispatch => {
        return {
            delayData: () => dispatch(delayData)
        };
    };
    
    const delayDataAction = {
        type: DALAY_DATA
    };
    
    export const delayData = dispatch => {
        delayDataTask(dispatch, delayDataAction);
    };
    

    saga采用的方案更接近于redux的全局思想,使用方式和thunk有很大不同:

    saga需要一个全局监听器(watcher saga),用于监听组件发出的action,将监听到的action转发给对应的接收器(worker saga),再由接收器执行具体任务,任务执行完后,再发出另一个action交由reducer修改state,所以这里必须注意:watcher saga监听的action和对应worker saga中发出的action不能是同一个,否则造成死循环。

    在saga中,全局监听器和接收器都使用Generator函数和saga自身的一些辅助函数实现对整个流程的管控。

    整个流程可以简单描述为:

    Component —> Action1 —> Watcher Saga —> Worker Saga —> Action2 —> Reducer —> Component

    相比thunk,saga是多了一个action的,因为saga是将业务的触发(watcher saga)和业务的执行(worker saga)分开描述的。

    const getCountAction = (param) => {
        return {
            type: 'count',
            param
        }
    }
    
    const getCountFinishAction = (param) => {
        return {
            type: 'countFinish',
            param
        }
    }
    
    const mapDispatchToProps = (dispatch) => {
        return {
            count: (param) => {
                return dispatch(getCountAction(param))//这里dispatch的参数是个普通对象
            }
        }
    }
    
    //一个普通函数 将当前计数+1
    function counter(curCount) {
        return ++curCount
    }
    
    //worker saga 这里其实是有接收参数的 这个参数action就是redux执行dispatch方法中的参数
    function* counterSaga(action) {
        console.log(`counterSaga receive the action ${action.type}`)
        //接受到这个action之后 执行saga的call方法 call方法会执行counter函数 并将当前计数作为它的参数
        const countResult = yield call(counter, action.param)
        //counter执行的结果作为另一个action的参数
        yield put(getCountFinishAction(countResult))
    }
    
    //watcher saga 监听takeEvery这个action 并执行helloSaga
    function* watchIncrementAsync() {
        console.log('watcher saga is listening to action')
        yield* takeEvery('count', counterSaga);
    }
    
    //执行watcher saga 这样就可以一直监听应用中的action了
    sagaMiddleware.run(watchIncrementAsync)
    

    相关文章

      网友评论

          本文标题:redux-saga基本用法

          本文链接:https://www.haomeiwen.com/subject/jglnzhtx.html