多个 redux-sagas
Multiple redux-sagas
我将 react-redux 和 redux-saga 用于来自 this 示例的 API 调用。我的目标是使用不同的 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,我将在另一个组件中使用它,并且两者不会相互混淆。这可能吗?
当然,这就是传奇的全部意义。
一个典型的应用程序会有多个 sagas 在后台等待,等待一个或多个特定的动作(take
效果)。
下面是如何从 redux-saga issue#276 设置多个 sagas 的示例:
./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)
Redux Saga 在最新版本 (0.15.3) 中使用 all
功能将多个 sagas 合并为一个 root saga 用于 Redux store。
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 商店中,您可以将 root saga 用于 saga 中间件:
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)
自上次发布答案以来,这发生了一些变化。如 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 与其父级断开连接的效果,允许它失败而不会使其父级崩溃。这只是意味着即使一个 saga 失败,rootSaga
和其他 saga 也不会被杀死。
还有一种方法可以恢复失败的传奇(有关更多信息,请参见上面提到的 link)。
作为最佳实践,您首先应该创建 API 文件,其中包含您想要的所有 API 调用。然后在您需要处理的 saga 中导入您需要的 API,然后将相同的 saga 用于多个任务。然后在这样做之后你应该创建 rootSaga 来处理所有的传奇,因为人们已经为你回答了你的每个传奇并在数组中使用 All 然后你就完成了(最佳实践因为会向你展示很多领域redux-saga ...)
的流程有点模糊
我将 react-redux 和 redux-saga 用于来自 this 示例的 API 调用。我的目标是使用不同的 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,我将在另一个组件中使用它,并且两者不会相互混淆。这可能吗?
当然,这就是传奇的全部意义。
一个典型的应用程序会有多个 sagas 在后台等待,等待一个或多个特定的动作(take
效果)。
下面是如何从 redux-saga issue#276 设置多个 sagas 的示例:
./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)
Redux Saga 在最新版本 (0.15.3) 中使用 all
功能将多个 sagas 合并为一个 root saga 用于 Redux store。
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 商店中,您可以将 root saga 用于 saga 中间件:
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)
自上次发布答案以来,这发生了一些变化。如 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 与其父级断开连接的效果,允许它失败而不会使其父级崩溃。这只是意味着即使一个 saga 失败,rootSaga
和其他 saga 也不会被杀死。
还有一种方法可以恢复失败的传奇(有关更多信息,请参见上面提到的 link)。
作为最佳实践,您首先应该创建 API 文件,其中包含您想要的所有 API 调用。然后在您需要处理的 saga 中导入您需要的 API,然后将相同的 saga 用于多个任务。然后在这样做之后你应该创建 rootSaga 来处理所有的传奇,因为人们已经为你回答了你的每个传奇并在数组中使用 All 然后你就完成了(最佳实践因为会向你展示很多领域redux-saga ...)
的流程有点模糊