我使用的redux-saga
花了一些时间在发电机的核心概念上,有承诺的生成器,以及redux-saga本身。下面我想要的是理解什么是惯用的,什么是推荐的,什么不是。
在一个文件中,我定义了我的根传奇、观察者传奇和一个员工传奇(fetchSupplierOrders
)。
import {
fetchSupplierOrders,
} from './supplierOrders';
import { takeLatest} from 'redux-saga/effects';
function* watchSupplierOrdersSagas() {
yield takeLatest('REQUEST_FETCH_SUPPLIER_ORDERS', fetchSupplierOrders);
}
export default function* rootSaga() {
yield all([watchSupplierOrdersSagas()]);
}
这是工人的传奇故事:
export function* fetchSupplierOrders() {
try {
const supplierOrders = yield call(getSupplierOrders); // API call is in getSupplierOrders
// normally here I would use redux-saga put to hit my redux reducers
yield supplierOrders.map(({ id }) => id)
} catch (error) {
yield put({ type: 'RECEIVE_ERROR_FETCH_SUPPLIER_ORDERS', error: error.message });
}
}
我有一个,当我点击一个按钮时,它执行员工传奇。我在这里要做的是,根本不去经历残存的传奇故事。我将在组件中自己执行生成器函数,并遍历它。通常,我会通过观察者的故事,它会叫一个工人的传奇,它会产生副作用,通过修改redux状态。
但是,如果我想发出网络请求,但我不想将结果保存在redux中,而是以本地组件状态保存,那么怎么办?我希望组件能够直接从工人的传奇中得到结果。
下面是React组件中按钮的单击处理程序:
const handleFetchSuppliers = event => {
const it = fetchSupplierOrders({ payload: event.target.value });
const res1 = await it.next().value;
console.log('res1', res1);
const res2 = it.next(res1);
console.log('res2', res2);
这段代码将无法工作,因为在worker协议中,我使用的是redux-saga
的call
函数。如果我删除了call
的使用,直接调用getSupplierOrders
(一个异步函数),那么等待工作和所有正确的值都是console.logged。
这样做是否很常见(从组件中执行worker saga以获得API请求的结果)?但是,如果我这样做,那么我就失去了使用call的好处(这不是很有用吗,因为它更容易测试?)
在使用redux-saga
之前,我只需要使用redux-thunk
发出一个提示,这基本上就是使用async/await
。
人们是否混合使用redux-thunk
和redux-saga
?这是不同意的吗?
发布于 2019-07-12 04:37:21
但是,如果我想发出网络请求,但我不想将结果保存在redux中,而是以本地组件状态保存,那么怎么办?
如果不涉及redux,那么redux-saga就不是使用的合适工具。只需使用正常的反应方式:发出api请求(通常在componentDidMount中),然后等待承诺完成(使用.then或等待),然后调用setState。
如果您想要有多种方法来进行提取(包括通过一个传奇和一个直接调用),那么您可以将fetch放到一个助手函数中(常规函数,而不是生成器)。然后,组件和saga都可以使用助手函数,每个函数都用需要做的任何额外工作来包装它。
例如:
// helper
async function fetchStuff() {
const response = await fetch('some Url');
if (!response.ok) {
throw response.status;
}
const data = await response.json();
return data.map(({ id }) => id);
}
// In a saga...
function* watchFetch() {
yield takeLatest('doFetch', fetchStuffSaga);
}
function* fetchStuffSaga() {
try {
const data = yield call(fetchStuff);
yield put({ type: 'success', payload: data });
} catch (err) {
yield put({ type: 'error', payload: err });
}
}
// In a component that dispatches an action:
componentDidMount() {
this.props.dispatch({ type: 'doFetch' });
}
// In a component that doesn't want to dispatch an action:
async componentDidMount() {
try {
const data = await fetchStuff();
this.setState({ data });
} catch (err) {
this.setState({ error: err });
}
}
此代码将无法工作,因为在worker saga中,我使用的是redux的调用函数。如果我删除调用的使用,直接调用getSupplierOrders (一个异步函数),那么等待工作和所有正确的值都是console.logged。
Sagas不是用于手动迭代的。如果你试图手动迭代一个传奇,你要么需要有专门的知识,确切地说,什么是传奇会产生什么样的顺序,或者你基本上需要重新实现自己的redux-saga。前者是脆弱和紧密耦合的,后者是浪费精力。
这样做是否很常见(从组件中执行worker saga以获得API请求的结果)?
不是的。
人们会不会混合使用redux-thunk和redux-saga?这是不同意的吗?
它们都试图处理相同类型的事情(异步操作)。如果您只使用一种方法,然后尝试混合并匹配这两种方法,代码库就会更简单。
https://stackoverflow.com/questions/56998491
复制相似问题