Similar questions have been asked before, but the answers have not been of any help to me.
What are selectors in redux?
How to get something from the state / store inside a redux-saga function?
I think that I have a different setup since I cannot seem to be able to access state from my saga.
I tried doing:
const getList = store => store; const getList = state=> state;
these both return undefined
.
My store looks like this...
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; }
And I want to access my list in this 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); }
But like I said, both state
and store
are undefined.
So, how do I access my store (or state) in the saga?
A "selector function" is any function that accepts the Redux store state (or part of the state) as an argument, and returns data that is based on that state. A selector function can have any name you want.
First we import our Saga from the ./sagas module. Then we create a middleware using the factory function createSagaMiddleware exported by the redux-saga library. Before running our helloSaga , we must connect our middleware to the Store using applyMiddleware . Then we can use the sagaMiddleware.
You can assert the return value of a saga via the returns method. This only works for the top-level saga under test, meaning other sagas that are invoked via call , fork , or spawn won't report their return value.
You will have to use selectors for that. I'll give a simple example. Create a file selectors.js
and add the fields you want to select from your store, as shown below.
export const username = (state) => state.user.name;
Then in your saga, import the selectors as,
import * as selectors from './selectors';
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); }
the constant username
in sampleSaga
will now hold the username value from state.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With