如何在redux-saga函数中从状态/存储中获取某些内容?

161

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

简短回答:

import { select } from 'redux-saga/effects';
...
let data = yield select(stateSelectorFunction);
3个回答

295

正如 @markerikson 已经说过的那样,redux-saga 提供了一个非常有用的 API select(),用于在 saga 内部调用 selector 从 state 中获取部分数据。

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

/*
 * 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});
  }
}

除了由@markerikson建议的文档外,D. Abramov还制作了一个非常好的视频教程,介绍如何在Redux中使用selectors。同时,也可以查看Twitter上非常有趣的这个帖子。


3
正是我想要的...我简直不敢相信我错过了它。 - Adam Tal

39

“选择器”函数就是为此而生的。您将整个状态树传递给它们,它们返回一些状态的部分。调用选择器的代码不需要知道数据在状态中的位置,只需知道已返回数据。有关示例,请参见http://redux.js.org/docs/recipes/ComputingDerivedData.html

在saga中,可以使用select() API来执行选择器。


有趣的是,这篇文章是在被接受的答案发布之前3.5小时就写好了,但它没有提供示例,所以未能被采纳。无论如何,谢谢! - Aleksandar
1
@Casper - 我同意!但问题不在于你回答问题的速度,而在于你的回答有多好。我认为答案必须简单易读。这个答案并没有达到这个要求,而被采纳的答案更容易理解。 - Adam Tal
@AdamTal 是的,我同意 :) - Aleksandar

3
我使用了一个事件通道(eventChannel)来从生成器函数内的回调中分发一个动作(action)。
import {eventChannel} from 'redux-saga';
import {call, take} from 'redux-saga/effects';

function createEventChannel(setEmitter) {
    return eventChannel(emitter => {
        setEmitter(emitter)
        return () => {

        }
      }
    )
}

function* YourSaga(){
    let emitter;
    const internalEvents = yield call(createEventChannel, em => emitter = em)

    const scopedCallback = () => {
        emitter({type, payload})
    }

    while(true){
        const action = yield take(internalEvents)
        yield put(action)
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接