首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >用redux-saga的习惯用法是直接从反应组件中调用员工传奇吗?

用redux-saga的习惯用法是直接从反应组件中调用员工传奇吗?
EN

Stack Overflow用户
提问于 2019-07-11 23:26:48
回答 1查看 1.8K关注 0票数 1

我使用的redux-saga花了一些时间在发电机的核心概念上,有承诺的生成器,以及redux-saga本身。下面我想要的是理解什么是惯用的,什么是推荐的,什么不是。

在一个文件中,我定义了我的根传奇、观察者传奇和一个员工传奇(fetchSupplierOrders)。

代码语言:javascript
运行
复制
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()]);
}

这是工人的传奇故事:

代码语言:javascript
运行
复制
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组件中按钮的单击处理程序:

代码语言:javascript
运行
复制
    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-sagacall函数。如果我删除了call的使用,直接调用getSupplierOrders (一个异步函数),那么等待工作和所有正确的值都是console.logged。

这样做是否很常见(从组件中执行worker saga以获得API请求的结果)?但是,如果我这样做,那么我就失去了使用call的好处(这不是很有用吗,因为它更容易测试?)

在使用redux-saga之前,我只需要使用redux-thunk发出一个提示,这基本上就是使用async/await

人们是否混合使用redux-thunkredux-saga?这是不同意的吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-07-12 04:37:21

但是,如果我想发出网络请求,但我不想将结果保存在redux中,而是以本地组件状态保存,那么怎么办?

如果不涉及redux,那么redux-saga就不是使用的合适工具。只需使用正常的反应方式:发出api请求(通常在componentDidMount中),然后等待承诺完成(使用.then或等待),然后调用setState。

如果您想要有多种方法来进行提取(包括通过一个传奇和一个直接调用),那么您可以将fetch放到一个助手函数中(常规函数,而不是生成器)。然后,组件和saga都可以使用助手函数,每个函数都用需要做的任何额外工作来包装它。

例如:

代码语言:javascript
运行
复制
// 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?这是不同意的吗?

它们都试图处理相同类型的事情(异步操作)。如果您只使用一种方法,然后尝试混合并匹配这两种方法,代码库就会更简单。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56998491

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档