Redux-saga not picking up action dispatch

I am using redux-saga in a new create-react-app react project with redux and for some reason it seems redux-saga is not picking up the dispatched action. A console log statement in the reducer shows the action does reach the reducer. The odd thing about all this is that I've based this project off other projects where I have successfully used redux-saga (but are not create-react-app's). I'm wondering if it is a versioning issue or some support package is required that I am missing. Below is a full code snippet.

From my package.json file:

 "dependencies": { "axios": "^0.19.0", "connect-history-api-fallback": "^1.6.0", "connected-react-router": "^6.5.2", "react": "^16.9.0", "react-dom": "^16.9.0", "react-google-login": "^5.0.5", "react-redux": "^7.1.1", "react-router-dom": "^5.0.1", "react-scripts": "3.1.1", "redux": "^4.0.4", "redux-actions": "^2.6.5", "redux-immutable-state-invariant": "^2.1.0", "redux-persist": "^5.10.0", "redux-saga": "^1.0.5", "shortid": "^2.2.14", "styled-components": "^4.3.2", "styled-modern-normalize": "^0.2.0" }, "devDependencies": { "react-hot-loader": "^4.12.11", "history": "^4.9.0" }, 

the outer most index.js file (entry point for my app):

import React from 'react'; import ReactDOM from 'react-dom'; import { Provider } from 'react-redux'; import App from './components/App'; import store from './store/config'; const render = (Component) => { ReactDOM.render( <Provider store={store}> <Component /> </Provider>, document.querySelector('#root') ); }; render(App); 

the app.js file is basically a container component with a connected router from connected-react-router which has the app header and then a switch with the app routes. I'm not showing it because it is actually a few nested components and it may just confuse.

I create my store like this:

import { applyMiddleware, compose, createStore, } from 'redux'; import createSagaMiddleware from 'redux-saga'; import rootReducer from '../root/rootReducer'; import sagas from '../root/rootSaga'; const sagaMiddleware = createSagaMiddleware(); const initialState = undefined; const store = createStore( rootReducer(history), initialState, applyMiddleware(sagaMiddleware), ); sagaMiddleware.run(sagas); export default store; 

Next is the root reducer:

import { combineReducers } from 'redux'; import { connectRouter } from 'connected-react-router'; import authReducer from '../auth/authReducer'; import { stateKeys } from '../../types'; export default history => combineReducers({ [stateKeys.ROUTER]: connectRouter(history), [stateKeys.AUTH]: authReducer, }); 

and root saga:

import { watchRegister, watchSignin, watchSignout, } from '../auth/authSaga'; const root = function* rootSaga() { yield [ watchRegister(), watchSignin(), watchSignout(), ]; }; export default root; 

My auth Saga:

import { call, put, takeEvery, takeLatest } from 'redux-saga/effects'; import api from '../../services/api'; import * as actions from '../root/rootActions'; function* signInSaga({ payload }) { try { console.log('saga hit...'); // console.log('email: ', email); // console.log('password: ', password); // yield put(actions.signinRequested()); // const response = yield call(api.signin, { email, password }); // console.log('response: ', response); // yield put(actions.signinSucceeded(response)); } catch (error) { console.log('saga failed...'); yield put(actions.signinFailed()); } } export function* watchSignin() { yield takeEvery(actions.signin.toString(), signInSaga); } 

auth actions:

import { createAction } from 'redux-actions'; export const signin = createAction('auth/signin'); export const signinRequested = createAction('auth/signin_requested'); export const signinSucceeded = createAction('auth_signin_succeeded'); export const signinFailed = createAction('auth_signin_failed'); 

finally the signin component:

import React, { Component, Fragment} from 'react'; import PropTypes from 'prop-types'; import { connect } from 'react-redux'; import { Link, Redirect } from 'react-router-dom'; import * as actions from '../../store/root/rootActions'; import * as selectors from '../../store/root/rootSelectors'; class Signin extends Component { ... onSubmitClick = (event) => { event.preventDefault(); this.setState({ loading: true }); const { email, password } = this.state; const user = { email, password }; // dispatching the action this.props.signin(user); }; renderSigninForm() { const { email, password } = this.state; return ( <form className="ui large form"> <div className="ui stacked segment"> <div className="field"> <div className="ui left icon input"> <i className="user icon"></i> <input onChange={this.handleChange("email")} type="email" placeholder="" value={email} /> </div> </div> <div className="field"> <div className="ui left icon input"> <i className="lock icon"></i> <input onChange={this.handleChange("password")} type="password" placeholder="Password" value={password} /> </div> </div> <div onClick={this.onSubmitClick} className="ui fluid large primary submit button">Log in</div> </div> </form> ); } render() { if (this.state.redirectToReferer) { return <Redirect to="/" />; } return ( <div className="ui middle aligned center aligned grid"> <div className="column"> <h2 className="content">Signin</h2> {this.renderSigninForm()} </div> </div> ); } } const mapStateToProps = state => ({ auth: selectors.getAuth(state), }); const mapDispatchToProps = dispatch => ({ signin: user => dispatch(actions.signin(user)), }); export default connect(mapStateToProps, mapDispatchToProps)(Signin); 

I apologize for the epic length of this post but it's hard to provide a complete code snippet without everything. Any suggestions are welcome :) Thanks in advance

1

1 Answer

Seems that your root saga file is not calling a saga method to start your sagas. As the documentation says: you should call all() method to run your saga setup. (e.g ).

so your refactored rootSaga.js would look like this:

import { all } from 'redux-saga/effects' import { watchRegister, watchSignin, watchSignout, } from '../auth/authSaga'; const root = function* rootSaga() { yield all([ watchRegister(), watchSignin(), watchSignout(), ]); }; export default root; 
0

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

You Might Also Like