Redux Saga选择器,如何从Saga中访问状态?

35

之前已有类似问题,但答案对我没有任何帮助。

Redux中的selectors是什么?

如何在redux-saga函数中从state / store获取数据?

我认为我的设置不同,因为我似乎无法从我的saga中访问状态。

我尝试做:

const getList = store => store;
const getList = state=> state;

这两者都返回undefined

我的商店看起来像这样...

export default function createStoreWithMiddleware() {
    const sagaMiddleware = createSagaMiddleware();
    const loggerMiddleware = createLogger();
    const middleware = [sagaMiddleware, loggerMiddleware];
    const persistedState = localStorage.getItem('reduxState') ? JSON.parse(localStorage.getItem('reduxState')) : {};

    const store = createStore(reducer, persistedState, compose(
        applyMiddleware(...middleware)
    ));

    store.subscribe(() => {
        localStorage.setItem('reduxState', JSON.stringify(store.getState()));
    });

    sagaMiddleware.run(rootSaga);

    return store;
}

我希望在这个saga中访问我的列表:

function* selectTender(action) {
    try {
        const response = yield Api.getTenderById(action.payload);
        yield put({type: 'SELECT_TENDER_SUCCEEDED', currentTender: response});
        const list = yield select(getList);
        yield put({type: 'FETCH_CHAPTERS', chaptersList: list, tenderId: response.id});
    } catch (err) {
        yield put({type: 'SELECT_TENDER_FAILED', message: err.message});
    }
}

export function* watchSelectTender(){
    yield takeEvery('SELECT_TENDER', selectTender);
}

但正如我所说,statestore都未定义。

那么,在saga中如何访问我的存储(或状态)?

2个回答

68
您需要使用选择器来实现这一点。我将提供一个简单的例子。 创建一个名为selectors.js的文件,并添加您想要从您的存储中选择的字段,如下所示。
export const username = (state) => state.user.name;

然后在你的 saga 中,将选择器导入为:

import * as selectors from './selectors';

当您需要在saga中使用username时,您只需执行以下操作:

and when you require username in your saga, you can simply do,

import {select} from 'redux-saga/effects';
...
...
function *sampleSaga(params) {
   const username = yield select(selectors.username);
}

sampleSaga 中的常量 username 现在将保存来自状态的用户名值。


我尝试过了,但是就像我说的那样,状态返回未定义 :( - Winter
1
其实它成功了!我之前调试错了。当我使用整个 yield select(selectors.username); 时,它就像魔术一样奏效 :) - Winter
这太棒了。谢谢! - JonnyBeoulve
我可以像这样在函数中封装状态吗?function getUserName(params) { const username = yield select(selectors.username); return username; } - ruandao
@ruandao 是的,如果 getUserName 是一个生成器函数,你可以这样做。 - Vishal Sharma
谢谢!只是不要忘记在 select(...) 前面加上 yield... - Filip Savic

0

看起来事情可能有些变化。不确定,redux-saga文档没有帮助我解决问题。可能是我的存储设置方式不同。但如果你在2021年卡住了,这可能会有所帮助:

我有一个状态,其中包含属性“currentUser”,而“currentUser”又具有属性“id”。我需要这个ID。

const getUser = (state) => state.get('currentUser')

function* addItem() {
    const currentUser = yield select(getUser)
    const id = currentUser.get('id')
    debugger
}

function* itemQuantitySaga() {
    yield all([takeLatest(INCREASE_ITEM_QUANTITY, addItem)])
}



你在那个文件中导入了状态吗? - vallard
1
这是将状态作为参数传递的redux-saga中间件。 - OctaviaLo

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