最近,我们开始使用 redux-saga 中间件来管理来自商店的异步 API 调用。
以前,我们使用基于通用承诺的操作,一旦我们可以直接在操作本身上使用 async/await
和 .then()
以及 .catch()
,这使得管理组件流变得容易。
承诺:
const fetchCars = async () => {
const {data} = await fetchCarsRequest();
setCars(data);
}
cars.map((car) => <li>{car.name}</li>);
关于传奇:
function* fetchCarsSaga() {
try {
const {data} = yield call(fetchCarsService);
yield put(fetchCarsSuccess);
} catch(error) {
yield put(fetchCarsFailure);
}
}
const fetchCars = async () => {
fetchCarsRequest(); //action that calls the above saga
setCars(cars); //state from store
}
cars.map((car) => <li>{car.name}</li>);
在第二个示例中,即使我们使用生成器来处理异步 API 调用也很困难,但无法使用 await
语句,因此它在 {{1} 之后立即调用 setCars
函数}} 被调用,试图为组件状态设置一些尚不存在的东西。
所以我的问题是:有没有办法替换 fetchCarsRequest
语句并等待请求函数(不是异步函数)完成 API 调用?
答案 0 :(得分:1)
使用 redux-saga,流程会有所不同。您不直接在组件中使用生成器。您需要从 saga 更新 redux 状态并在组件中获取它。
react component -> redux action -> saga -> redux state -> react component
您可以查看的 PT-BR 中的两篇文章是:
一个好的 create-react-app
模板是:
在代码沙盒中:
答案 1 :(得分:0)
您想分派一个操作 #display{ font-family: monospace; }
来触发 API 调用并将结果保存到您的 redux 存储中。您希望等待此操作完成,然后调用 <div id="buttonContainer">
<button data-number="Infinity">Default</button>
<button data-number="2">Last Two</button>
<button data-number="3">Last Three</button>
<button data-number="4">Last Four</button>
</div>
<hr/>
<div id="display"></div>
将您的组件状态设置为来自 redux 状态的值。为什么?
这是一种反模式。数据已经存在于 redux 中,应该直接从组件中的 redux 访问。您应该使用 fetchCarsRequest()
或 setCars(cars)
HOC 从 redux 中选择 useSelector
的值。一旦您的提取已分派 connect
并更新商店状态,它会自动使用新数据重新呈现您的组件。
它应该看起来像这样。
传奇
cars
组件
fetchCarsSuccess