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

时间:2022-12-28 10:45:15

How do I access the redux state inside a saga function?

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

My Problem

I have an application consisting of the following parts:

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

            TOOLBAR        
 ---------------------------------
 User info     |   Current Project

Each part is a different component with it's own reducer, saga, actions and state.

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

The toolbar has a save button which dispatches a "SAVE_PROJECT" action type. The problem is that I don't want the toolbar to know the project (it has more responsibilities and I just want it to dispatch actions with type).

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

I have a project related saga which listens to the "SAVE_PROJECT":

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

...
export function* saveProjectTask() {
  while(true) {
    yield take(SAVE_PROJECT);
    let project = /* THIS IS THE PROBLEM, I DON'T HAVE THE PROJECT */;
    yield call(fetch, '/api/project', { body: project, method: 'PUT' });
    yield put({type: SAVE_PROJECT_SUCCESS});
  }
}

I can't get the project from the redux state inside the saga.

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

I don't think I can listen to the "SAVE_PROJECT" event inside the curren project reducer and then inside the reducer get the project and dispatch a different action with the project.

我不认为我可以在当前项目减速器中听取“SAVE_PROJECT”事件,然后在reducer内部获取项目并向项目发送不同的动作。

I really don't want my toolbar to know the entire state tree and send anything related to the action for every action.

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

How can I pass the state it-self to the saga? Or only the relevant part of the state?

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

2 个解决方案

#1


98  

As @markerikson already says, redux-saga exposes a very useful API select() to invoke a selector on the state for getting some part of it available inside the saga.

正如@markerikson已经说过的那样,redux-saga公开了一个非常有用的API select()来调用状态选择器,以便在saga中获取它的一部分。

For your example a simple implementation could be:

对于您的示例,一个简单的实现可能是:

/*
 * Selector. The query depends by the state shape
 */
export const getProject = (state) => state.project

// Saga
export function* saveProjectTask() {
  while(true) {
    yield take(SAVE_PROJECT);
    let project = yield select(getProject); // <-- get the project
    yield call(fetch, '/api/project', { body: project, method: 'PUT' });
    yield put({type: SAVE_PROJECT_SUCCESS});
  }
}

In addition to the suggested doc by @markerikson, there is a very good video tutorial by D. Abramov which explains how to use selectors with Redux. Check also this interesting thread on Twitter.

除了@markerikson建议的文档之外,还有一个非常好的视频教程,由D. Abramov解释如何使用Redux的选择器。在Twitter上查看这个有趣的帖子。

#2


15  

This is what "selector" functions are for. You pass them the entire state tree, and they return some piece of the state. The code that calls the selector doesn't need to know where in the state that data was, just that it was returned. See http://redux.js.org/docs/recipes/ComputingDerivedData.html for some examples.

这就是“选择器”功能的用途。你将它们传递给整个状态树,然后它们返回一些状态。调用选择器的代码不需要知道数据的状态在哪里,只需返回它。有关示例,请参阅http://redux.js.org/docs/recipes/ComputingDerivedData.html。

Within a saga, the select() API can be used to execute a selector.

在一个传奇中,select()API可用于执行选择器。

#1


98  

As @markerikson already says, redux-saga exposes a very useful API select() to invoke a selector on the state for getting some part of it available inside the saga.

正如@markerikson已经说过的那样,redux-saga公开了一个非常有用的API select()来调用状态选择器,以便在saga中获取它的一部分。

For your example a simple implementation could be:

对于您的示例,一个简单的实现可能是:

/*
 * Selector. The query depends by the state shape
 */
export const getProject = (state) => state.project

// Saga
export function* saveProjectTask() {
  while(true) {
    yield take(SAVE_PROJECT);
    let project = yield select(getProject); // <-- get the project
    yield call(fetch, '/api/project', { body: project, method: 'PUT' });
    yield put({type: SAVE_PROJECT_SUCCESS});
  }
}

In addition to the suggested doc by @markerikson, there is a very good video tutorial by D. Abramov which explains how to use selectors with Redux. Check also this interesting thread on Twitter.

除了@markerikson建议的文档之外,还有一个非常好的视频教程,由D. Abramov解释如何使用Redux的选择器。在Twitter上查看这个有趣的帖子。

#2


15  

This is what "selector" functions are for. You pass them the entire state tree, and they return some piece of the state. The code that calls the selector doesn't need to know where in the state that data was, just that it was returned. See http://redux.js.org/docs/recipes/ComputingDerivedData.html for some examples.

这就是“选择器”功能的用途。你将它们传递给整个状态树,然后它们返回一些状态。调用选择器的代码不需要知道数据的状态在哪里,只需返回它。有关示例,请参阅http://redux.js.org/docs/recipes/ComputingDerivedData.html。

Within a saga, the select() API can be used to execute a selector.

在一个传奇中,select()API可用于执行选择器。