标签: redux-saga

使用带有ES6发生器的redux-saga与带有ES2017异步/等待的redux-thunk的优点/缺点

现在有很多关于redux镇最新孩子的讨论,redux-saga/redux-saga.它使用生成器函数来监听/调度操作.

在我绕过它之前,我想知道redux-saga使用redux-thunkasync/await时使用的优点/缺点而不是下面的方法.

组件可能看起来像这样,像往常一样调度动作.

import { login } from 'redux/auth';

class LoginForm extends Component {

  onClick(e) {
    e.preventDefault();
    const { user, pass } = this.refs;
    this.props.dispatch(login(user.value, pass.value));
  }

  render() {
    return (<div>
        <input type="text" ref="user" />
        <input type="password" ref="pass" />
        <button onClick={::this.onClick}>Sign In</button>
    </div>);
  } 
}

export default connect((state) => ({}))(LoginForm);
Run Code Online (Sandbox Code Playgroud)

然后我的行为看起来像这样:

// auth.js

import request from 'axios';
import { loadUserData } from './user';

// define constants
// define initial state
// export default reducer …
Run Code Online (Sandbox Code Playgroud)

javascript reactjs redux redux-thunk redux-saga

449
推荐指数
6
解决办法
10万
查看次数

为什么在Redux-Saga上使用Redux-Observable?

我使用过Redux-Saga.用它编写的代码到目前为止很容易理解,除了JS生成器功能不时弄乱我的脑袋.根据我的理解,Redux-Observable可以实现处理副作用但不使用生成器功能的类似工作.

然而,来自Redux-Observable的文档并没有提供很多关于它为什么优于Redux-Saga的观点.我想知道是否使用生成器函数是使用Redux-Observable的唯一好处.使用Redux-Observable而不是Redux-Saga会有什么缺点,不足或妥协?提前致谢.

javascript reactive-programming redux redux-saga redux-observable

122
推荐指数
6
解决办法
3万
查看次数

如何从redux-saga函数中的状态/商店中获取内容?

如何在saga函数中访问redux状态?

我的问题

我有一个由以下部分组成的应用程序:

import { select } from 'redux-saga';
...
let data = yield select(stateSelectorFunction);
Run Code Online (Sandbox Code Playgroud)

每个部分都是一个不同的组件,它有自己的减速器,传奇,动作和状态.

工具栏有一个保存按钮,可以调度"SAVE_PROJECT"动作类型.问题是我不希望工具栏知道项目(它有更多的职责,我只是希望它发送类型的动作).

我有一个项目相关的传奇,它听取了"SAVE_PROJECT":

import { select } from 'redux-saga';
...
let data = yield select(stateSelectorFunction);
Run Code Online (Sandbox Code Playgroud)

我无法从传奇中的redux状态获得该项目.

我不认为我可以在当前项目reducer中听取"SAVE_PROJECT"事件,然后在reducer内部获取项目并向项目发送不同的操作.

我真的不希望我的工具栏知道整个状态树,并为每个动作发送与动作相关的任何内容.

我怎样才能将状态传递给传奇?还是只有国家的相关部分?

javascript reactjs redux redux-saga react-redux

95
推荐指数
2
解决办法
4万
查看次数

在redux-saga中的getState?

我有一个商品列表中的商品.当我的应用程序第一次加载时,我需要反序列化项目,就像在基于项目创建一些内存中对象一样.这些项目存储在我的redux商店中并由一个itemsReducer.

我试图使用redux-saga来处理反序列化,作为副作用.在第一页加载时,我发送一个动作:

dispatch( deserializeItems() );
Run Code Online (Sandbox Code Playgroud)

我的传奇很简单:

function* deserialize( action ) {
    // How to getState here??
    yield put({ type: 'DESERISLIZE_COMPLETE' });
}

function* mySaga() {
    yield* takeEvery( 'DESERIALIZE', deserialize );
}
Run Code Online (Sandbox Code Playgroud)

在我的deserialize saga中,我想要处理创建内存版本的项目的副作用,我需要从商店中读取现有数据.我不知道该怎么做,或者如果这是一种模式,我甚至应该尝试使用redux-saga.

javascript reactjs redux redux-saga

61
推荐指数
1
解决办法
3万
查看次数

47
推荐指数
2
解决办法
5万
查看次数

redux中的选择器是什么?

我想按照这个代码redux-saga

export const getUser = (state, login) => state.entities.users[login]
export const getRepo = (state, fullName) => state.entities.repos[fullName]
Run Code Online (Sandbox Code Playgroud)

然后将其像传奇使用:

import { getUser } from '../reducers/selectors'

// load user unless it is cached
function* loadUser(login, requiredFields) {
  const user = yield select(getUser, login)
  if (!user || requiredFields.some(key => !user.hasOwnProperty(key))) {
    yield call(fetchUser, login)
  }
}
Run Code Online (Sandbox Code Playgroud)

这种getUser减速器(甚至是减速器)与我通常期望的减速器看起来非常不同.

任何人都可以解释选择器是什么,getUser减速器是如何以及它如何适应redux-saga?

reactjs redux redux-saga

43
推荐指数
2
解决办法
1万
查看次数

启动rootSaga的惯用方法是什么?

redux-saga项目已经存在很长时间了,但是这个库仍然有很多令人困惑的事情.其中一个是:如何开始你的rootSaga.例如,在初学者教程中, rootSaga是通过一系列传奇来启动的.像这样

export default function* rootSaga() {
  yield [
    helloSaga(),
    watchIncrementAsync()
  ]
}
Run Code Online (Sandbox Code Playgroud)

然而,在使用传奇助手部分,rootSaga由两个分叉的传奇组成.像这样:

export default function* rootSaga() {
  yield fork(watchFetchUsers)
  yield fork(watchCreateUser)
}
Run Code Online (Sandbox Code Playgroud)

在redux-saga repo中的异步示例中使用了与启动rootSaga相同的方法.但是,如果你查看真实世界和购物卡的例子,你会看到rootSagas那里有一系列分叉的传奇.像这样:

export default function* root() {
  yield [
    fork(getAllProducts),
    fork(watchGetProducts),
    fork(watchCheckout)
  ]
}
Run Code Online (Sandbox Code Playgroud)

另外,如果您在redux-saga问题中阅读了一些讨论,您会看到有些人建议使用spawn而不是fork来为rootSaga保护应用程序完全崩溃,如果您的某个分叉传奇由于某些未处理的异常而被取消.

那么,哪种方式是启动rootSaga的最正确的方法?现有的有什么区别?

redux-saga

35
推荐指数
2
解决办法
6489
查看次数

redux-saga何时使用fork?

下面两种方法之间有什么区别?

export function* watchLoginUser() {
  yield takeEvery(USER_LOGIN, loginUser)
}
export function* watchLogoutUser() {
  yield takeEvery(USER_LOGOUT, logoutUser)
}
export function* watchGetParties() {
  yield takeEvery(PARTIES_GET, getParties)
}
export default function* root() {
  yield [
    fork(watchLoginUser),
    fork(watchLogoutUser),
    fork(watchGetParties)
  ]
}
Run Code Online (Sandbox Code Playgroud)
export default function* root() {
  yield [
    takeEvery(USER_LOGIN, loginUser),
    takeEvery(USER_LOGOUT, logoutUser),
    takeEvery(PARTIES_GET, getParties)
  ]
}
Run Code Online (Sandbox Code Playgroud)

我什么时候需要使用fork而不需要?

reactjs redux redux-saga

35
推荐指数
1
解决办法
1万
查看次数

Redux Saga异步/等待模式

我在整个代码库中使用async/await.因此,我的api调用由异步函数定义

async function apiFetchFoo {
  return await apiCall(...);
}
Run Code Online (Sandbox Code Playgroud)

我想从我的传奇代码中调用这个函数.好像我不能这样做:

// Doesn't work
function* fetchFoo(action) {
  const results = await apiFetchFoo();
  yield put({type: "FOOS_FETCHED_SUCCESSFULLY", foos: results});
}
Run Code Online (Sandbox Code Playgroud)

但是,这确实有效,并且与redux saga文档相匹配:

// Does work
function* fetchFoo(action) {
  const results = yield call(apiFetchFoo);
  yield put({type: "FOOS_FETCHED_SUCCESSFULLY", foos: results});
}
Run Code Online (Sandbox Code Playgroud)

这是使用Redux Saga和async/await的正确方法吗?在saga代码中使用这个生成器语法,在其他地方使用async/await模式是标准的吗?

redux redux-saga react-redux

33
推荐指数
2
解决办法
1万
查看次数

如何在加载路由时从无状态组件调度Redux操作?

目标:在加载反应路由器路由时,调度Redux操作,请求异步Saga工作程序获取该路由的基础无状态组件的数据.

问题:无状态组件仅仅是函数,没有生命周期方法,例如componentDidMount,所以我不能(?)从函数内部调度Redux操作.

我的问题部分与将有状态React组件转换为无状态功能组件有关:如何实现"componentDidMount"类功能?,但我的目标是仅发送一个Redux动作,要求将数据异步填充到商店(我使用Saga,但我认为这与问题无关,因为我的目标是仅发送一个普通的Redux动作),之后由于数据支柱的改变,无状态组件将重新渲染.

我正在考虑两种方法:使用react-router的一些功能,或Redux的connect方法.是否有一种所谓的"反应方式"来实现我的目标?

编辑:到目前为止我唯一提出的解决方案是在mapDispatchToProps中调度动作,这样:

const mapStateToProps = (state, ownProps) => ({
    data: state.myReducer.data // data rendered by the stateless component
});

const mapDispatchToProps = (dispatch) => {
    // catched by a Saga watcher, and further delivered to a Saga worker that asynchronically fetches data to the store
    dispatch({ type: myActionTypes.DATA_GET_REQUEST });
    return {};
};

export default connect(mapStateToProps, mapDispatchToProps)(MyStatelessComponent);
Run Code Online (Sandbox Code Playgroud)

然而,这似乎有点脏,而不是正确的方式.

reactjs redux-saga react-redux react-router-redux

28
推荐指数
3
解决办法
2万
查看次数