Multiple redux-sagas



本例中的API调用使用react-redux和redux-saga。我的目标是用不同的url做另一个API调用,并在不同的页面中使用它们。如何做到这一点?

传奇:

import { take, put,call } from 'redux-saga/effects';
import { takeEvery, delay ,takeLatest} from 'redux-saga';
function fetchData() {
    return  fetch("https://api.github.com/repos/vmg/redcarpet/issues?state=closed")
    .then(res => res.json() )
    .then(data => ({ data }) )
    .catch(ex => {
        console.log('parsing failed', ex);
        return ({ ex });
    });
}
function* yourSaga(action) {
    const { data, ex } = yield call(fetchData);
    if (data)
    yield put({ type: 'REQUEST_DONE', data });
    else
    yield put({ type: 'REQUEST_FAILED', ex });
}
export default function* watchAsync() {
    yield* takeLatest('BLAH', yourSaga);
}
export default function* rootSaga() {
    yield [
        watchAsync()
    ]
}
应用:

import React, { Component } from 'react';
import { connect } from 'react-redux';
class App extends Component {
    componentWillMount() {
        this.props.dispatch({type: 'BLAH'});
    }
    render(){
       return (<div>
            {this.props.exception && <span>exception: {this.props.exception}</span>}
            Data: {this.props.data.map(e=><div key={e.id}>{e.url}</div>)}
          </div>);
    }
}
export default connect( state =>({
    data:state.data , exception:state.exception
}))(App);

我的目标是制作另一个saga,我将在另一个组件中使用,并且两者都不会相互混淆。这可能吗?

Redux Saga在最新版本(0.15.3)中使用all函数将多个传奇合并为一个根传奇用于Redux存储。

import { takeEvery, all } from 'redux-saga/effects';
...
function *watchAll() {
  yield all([
    takeEvery("FRIEND_FETCH_REQUESTED", fetchFriends),
    takeEvery("CREATE_USER_REQUESTED", createUser)
  ]);
}
export default watchAll;

在Redux存储中,您可以为传奇中间件使用根传奇:

import { createStore, applyMiddleware } from 'redux';
import createSagaMiddleware from 'redux-saga';
import rootReducer from './reducers';
import rootSaga from './sagas';
const sagaMiddleware = createSagaMiddleware();
const store = createStore(
  rootReducer,
  applyMiddleware(sagaMiddleware)
);
sagaMiddleware.run(rootSaga)

当然,这就是传奇的全部意义。

一个典型的应用程序将有多个传奇在后台等待,等待一个特定的动作/动作(take效应)。

下面是一个如何从redux-saga issue#276中设置多个传奇的示例:

./saga.js

function* rootSaga () {
    yield [
        fork(saga1), // saga1 can also yield [ fork(actionOne), fork(actionTwo) ]
        fork(saga2),
    ];
}

./main.js

import { createStore, applyMiddleware } from 'redux'
import createSagaMiddleware from 'redux-saga'
import rootReducer from './reducers'
import rootSaga from './sagas'

const sagaMiddleware = createSagaMiddleware()
const store = createStore(
  rootReducer,
  applyMiddleware(sagaMiddleware)
)
sagaMiddleware.run(rootSaga)

自上次发布答案以来,这已经发生了一些变化。创建root saga的首选方法,如https://redux-saga.js.org/docs/advanced/RootSaga.html所述,是使用spawn:

export default function* rootSaga() {
  yield spawn(saga1)
  yield spawn(saga2)
  yield spawn(saga3)
}

spawn是一个效果,将断开你的子saga从它的父,允许它失败而不崩溃它的父。这意味着即使一个传奇失败了,rootSaga和其他传奇也不会被杀死。还有一种方法可以恢复失败的传奇故事(更多信息可以在上面提到的链接中找到)。

作为最佳实践,首先您应该创建具有您想要的所有API调用的API文件。然后将您需要的API导入到您需要处理的传奇中,然后将相同的传奇用于多个任务。然后,你应该创建rootSaga,它处理所有的saga,因为你已经回答了你的每个saga,并在一个数组中使用all,然后你就完成了(这是最好的做法,因为它会向你展示很多字段,这些字段在redux-saga的流程中有点模糊…)

相关内容

  • 没有找到相关文章

最新更新