Reputation: 47
I have this code in sagas.js
.
import { put, takeLatest } from "redux-saga/effects";
import { getArticles } from "../scripts/resources/articles";
import { GET_ARTICLES, SHOW_MATCHES } from "./constants";
function getMatches(action) {
const { searchValue } = action;
getArticles(searchValue, (matches) => {
console.log(matches)
put({ type: SHOW_MATCHES, payload: matches })
})
}
export default function* rootSaga() {
yield takeLatest(GET_MATCHES, getMatches);
}
And this is the getArticles
function.
export function getArticles(input, callBack) {
setTimeout(() => {
callBack(filterArticles(input));
}, 300);
};
The put inside the callback does not actually dispatch the action as I don't reach the case in the reducer. How can I dispatch this action?
Upvotes: 1
Views: 5594
Reputation: 571
First, just calling put()
won't pass a put effect to the channel of the saga unless preceded by yield
.
Second, yield
must be used inside a generator function, so you need to change the caller of yield put(...)
and the caller of its caller to the generator function form, that is
function *(){
yield anotherGeneratorFunction()
}
The following changed code just works
const { createStore, applyMiddleware } =require('redux')
const createSagaMiddleware =require('redux-saga').default
const { takeLatest ,take,put}=require('redux-saga/effects')
const {delay} =require('redux-saga')
const sagaMiddleware = createSagaMiddleware()
const reducer=(state=[],action)=>{return [...state,action.type];}
const store = createStore(
reducer,
applyMiddleware(sagaMiddleware)
)
function * getMatches(action) {
const { searchValue } = action;
yield getArticles(searchValue, function * (matches) {
console.log(matches)
yield put({ type: 'SHOW_MATCHES', payload: matches })
})
}
function * getArticles(input, callBack) {
yield delay(300)
yield callBack(filterArticles(input));
};
function filterArticles(input){
return ['artical1','artical2']
}
function* rootSaga() {
yield takeLatest('GET_MATCHES', getMatches);
}
sagaMiddleware.run(rootSaga)
store.dispatch({type:'GET_MATCHES',searchValue: 'test'})
setTimeout(() => {
console.log(store.getState())
}, 1000);
This will output
[ 'artical1', 'artical2' ]
[ '@@redux/INIT5.m.i.0.z.9', 'GET_MATCHES', 'SHOW_MATCHES' ]
Upvotes: 2