Redux英雄传奇未采取行动派遣

时间:2019-08-31 20:40:37

标签: reactjs redux redux-saga

我在一个新的带有redux的create-react-app react项目中使用redux-saga,由于某种原因,似乎redux-saga并未采取已调度的操作。 reducer中的控制台日志语句显示操作确实到达了reducer。奇怪的是,我已经将该项目基于我成功使用过redux-saga(但不是create-react-app)的其他项目。我想知道这是一个版本问题还是缺少一些支持包。以下是完整的代码段。

从我的package.json文件中:

  "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"
  },

最外面的index.js文件(我的应用程序的进入点):

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);

app.js文件基本上是一个容器组件,具有来自connected-react-router的已连接路由器,该路由器具有应用程序标头,然后是具有应用程序路由的交换机。我没有显示它,因为它实际上是一些嵌套的组件,可能会造成混淆。

我这样创建我的商店:

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;

接下来是根减速器:

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,
});

和根传奇:

import { 
  watchRegister,
  watchSignin,
  watchSignout,
} from '../auth/authSaga';

const root = function* rootSaga() {
  yield [
    watchRegister(),
    watchSignin(),
    watchSignout(),
  ];
};

export default root;

我的身份验证佐贺:

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

身份验证操作:

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');

最终登录组件:

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="john.smith@gmail.com" 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);

我为这篇文章的史诗般的长度表示歉意,但是如果没有所有内容,就很难提供完整的代码段。欢迎任何建议:)预先感谢

1 个答案:

答案 0 :(得分:1)

似乎您的 root saga 文件没有调用saga方法来启动sagas。如文档所述:您应该调用all()方法来运行传奇设置。 (例如https://redux-saga.js.org/docs/introduction/BeginnerTutorial.html)。

因此重构的rootSaga.js如下所示:

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;