如何设置 redux-sagas 和文件结构?
Posted
技术标签:
【中文标题】如何设置 redux-sagas 和文件结构?【英文标题】:how to setup redux-sagas and file structure? 【发布时间】:2018-09-17 02:57:49 【问题描述】:在我学习如何安装 jwt 并应用于我的 React native 之后,我正在使用 React-native、axios .所以我研究了一下redux, redux-thunk, redux-saga
,然后我选择了redux-saga
。
任何人都可以指导我设置 redux-sagas 之类的文件夹结构,代码拆分示例,我有 2 个页面,例如产品,固件。
在 redux-thunk 中
action/
/actionProduct.js
/actionFirmware.js
reducer/
/index.js
/productReducer.js
/firmwareReducer.js
store.js
index.js
但在 redux-sagas 中我开始感到困惑 它有 action、reducer、sagas 和 store 也是不同的设置。
const sagaMiddleware = createSagaMiddleware();
// mount it on the Store
const store = createStore(reducer, applyMiddleware(sagaMiddleware));
// then run the saga
sagaMiddleware.run(mySaga);
export default store;
在 redux-thunk 中我从未见过像这样的类似语法 sagaMiddleware.run(mySaga);
我需要创建 sagas 文件夹并添加 2 个 sagas,例如 productSagas、firmwareSagas 吗?
我需要写两行吗
sagaMiddleware.run(productSagas);
sagaMiddleware.run(firmwareSagas);
export default store;
或者我们可以设置动态存储?我该怎么做? 提前致谢。
新话题
我不确定我是否已正确设置此设置或不让查看我的设置。 Store.js
const sagaMiddleware = createSagaMiddleware();
const store = createStore(
rootReducer,
window.devToolsExtension && process.env.NODE_ENV !== 'production' ?
compose(
applyMiddleware(sagaMiddleware),
window.devToolsExtension(),
) :
applyMiddleware(sagaMiddleware),
);
sagaMiddleware.run(rootSaga);
export default store;
rootSaga 文件
export default function* rootSaga()
yield all([
firmwareWatcher(),
productWatcher(),
]);
rootReducer
export default const rootReducer = combineReducers(
firmware,
porduct,
);
App.js
class App extends Component
componentDidMount()
const dispatch = this.props;
dispatch( type: "FIRMWARE_REQUEST");
dispatch( type: 'PRODUCT_REQUEST');
....
const mapStateToProps = (state) =>
console.log(state);
return ... ;
;
这是我得到的 mapStateToProps 中的 console.log(state),我在 switch case 中使用 consone.log 来了解 ACTION TYPE
PRODUCT_SUCCESS
type: "PRODUCT_SUCCESS", payload: …, @@redux-saga/SAGA_ACTION: true
firmware: …, porduct: …
FIRMWARE_SUCCESS
type: "API_CALL_SUCCESS", payload: …, @@redux-saga/SAGA_ACTION: true
default
firmware: …, porduct: …
firmware: …, porduct: …
|
V
firmware : fetching: false, dog: null, error: null, data: "https://dog.ceo/api/img/retriever-golden/n02099601_2495.jpg"
porduct :
data : id: 120, name: "A1", image: "a1_12-16-2017-1513389068.jpg", price: "28.00", status: 1, …
【问题讨论】:
【参考方案1】:您不需要运行单个 saga,因为您使用的是 sagaMiddleware,所以您的所有操作都将通过您的 saga。我认为你在正确的轨道上 - 这是我设置 sagas 的方式。
为每个异步组件创建一个 saga,productSaga.js
和 firmwareSaga.js
。
然后为您的 sagas index-sagas.js
创建一个索引文件。这将从您的项目中导入所有 sagas 并将它们导出以在您的 index.js
文件中使用。
/// index-sagas.js ///
import productWatcher from './components/product/product-saga.js';
import firmwareWatcher from './components/firmware/firmware-saga.js';
export default function* IndexSagas()
yield [
productWatcher(),
firmwareWatcher(),
]
/// end of file ///
这是您在index.js
顶部导入的内容:
/// index.js ///
import IndexSagas from './index-sagas.js'
...
/// end of file ///
在product-saga.js
和firmware-saga.js
中创建一对生成器函数
/// product-saga.js ///
import PRODUCT_ACTION from './constants';
import productActionSuccess, productActionError from './actions';
export default function* productWatcher()
yield [
takeLatest(PRODUCT_ACTION, productActionFlow)
]
// This will be triggered any time PRODUCT_ACTION is dispatched and it
// will call the productActionFlow generator. This is
// where your async logic lives
function* productActionFlow(action)
try
const result = yield call(productGETRequest, action)
// productGETRequest is a function elsewhere in this file that
// will make your GET request
yield put(productActionSuccess(result))
// productActionSuccess is the action imported above
catch (error)
yield put(productActionError(error)
【讨论】:
Keller 看,它看起来像 Sagas 设置,比如 reducer 有 rootReducer 并将所有 saga 导入到 root。但是为什么要将 IndexSagas 导入 index.js 呢?我们是否将包含 store.js 中所有 saga 的 IndexSagas 导入到sagaMiddleware.run(IndexSagas);
right ?
Reaksmey,您将 IndexSagas 导入 index.js,因为需要告知 sagaMiddleware 项目中所有 sagas 的位置——它不会去寻找它们。你在你的 index.js 中告诉 sagaMiddleware 这个信息,如下所示:
--继续--sagaMiddleware.run(IndexSagas);
。如果您愿意,您也许可以运行每个单独的 saga,但这更简洁一些。我不相信sagaMiddleware.run(indexSagas);
会对您的商店进行任何更改。到那时你应该已经这样做了:const store = createStore(reducer, applyMiddleware(sagaMiddleware));
帮助检查我上面的答案编辑是否正确?毕竟感谢您的帮助。
Product Saga 和 Index Sagas 只是函数生成器,与 redux-saga 无关,需要连接 saga 中间件。这只是组织代码。很好的答案卢卡斯!以上是关于如何设置 redux-sagas 和文件结构?的主要内容,如果未能解决你的问题,请参考以下文章
使用 redux-saga 作为中间件,在 root saga 文件中使用的 All 效果和 Fork 效果都比较有用