Функция Redux Saga не вызывается - PullRequest
0 голосов
/ 07 мая 2018

Я пытался использовать redux-saga в моем проекте React, но функция redux-saga не вызывается. toggleLoginModal действие в access.actions.js вызывается, но toggleLoginModal в access.sagas.js не вызывается.

Header.jsx

import React, { Component } from 'react';
import { withRouter } from 'react-router';
import accessActions from 'actions/access.actions';
import { connect } from 'react-redux';
import './Header.scss';

const { toggleLoginModal, toggleRegisterModal } = accessActions;

class Header extends Component {
  handleLoginClick = () => {
    toggleLoginModal(true);
  };

  render() {
    return (
        <div className="navbar-right">
            <button type="button" className="btn btn-link" onClick={this.handleLoginClick}>Log in</button>
            <button type="button" className="btn btn-primary">Register</button>
        </div>
    );
  }
}

export default withRouter(connect(null, { toggleLoginModal, toggleRegisterModal })(Header));

access.action.js

const actions = {
  TOGGLE_LOGIN_MODAL: 'TOGGLE_LOGIN_MODAL',
  TOGGLE_LOGIN_MODAL_RETURN: 'TOGGLE_LOGIN_MODAL_RETURN',
  toggleLoginModal: newState => ({
    type: actions.TOGGLE_LOGIN_MODAL,
    state: newState,
  }),
  toggleLoginModalReturn: (newState) => {
    return (dispatch) => {
      dispatch({
        type: actions.TOGGLE_LOGIN_MODAL_RETURN,
        newState,
      });
    };
  },
};
export default actions;

access.sagas.js

import { all, takeEvery, put } from 'redux-saga/effects';
import actions from 'actions/access.actions';

export function* toggleLoginModal({ state }) {
  yield put(actions.toggleLoginModalReturn(state));
}

export default function* rootSaga() {
  yield all([
    takeEvery(actions.TOGGLE_LOGIN_MODAL, toggleLoginModal),
  ]);
}

access.reducers.js

export function toggleModals(state = { login: false, register: false }, action) {
  switch (action.type) {
    case 'TOGGLE_LOGIN_MODAL_RETURN':
      return { login: action.newState };
    default:
      return state;
  }
}

reducers.js

import { toggleModals } from 'state/access.reducers.js';

export default {
  toggleModals,
};

sagas.js

import { all } from 'redux-saga/effects';
import accessSagas from 'sagas/access.sagas';

export default function* rootSaga() {
  yield all([accessSagas()]);
}

index.jsx

import React from 'react';
import ReactDOM from 'react-dom';
import createHistory from 'history/createBrowserHistory';
import { createStore, combineReducers, applyMiddleware } from 'redux';
import { ConnectedRouter, routerReducer, routerMiddleware } from 'react-router-redux';
import { Provider } from 'react-redux';
import createSagaMiddleware from 'redux-saga';
import { composeWithDevTools } from 'redux-devtools-extension/developmentOnly';

import App from 'App';
import reducers from 'reducers';
import sagas from 'sagas';

const history = createHistory();
const sagaMiddleware = createSagaMiddleware();

const store = createStore(
  combineReducers({
    ...reducers,
    router: routerReducer,
  }),
  composeWithDevTools(applyMiddleware(
    routerMiddleware(history),
    sagaMiddleware,
  )),
);

sagaMiddleware.run(sagas);

ReactDOM.render(
  <Provider store={store}>
    <ConnectedRouter history={history}>
      <App />
    </ConnectedRouter>
  </Provider>,
  document.getElementById('app'),
);

package.json

"dependencies": {
    "bootstrap": "^4.1.1",
    "jquery": "^3.3.1",
    "js-cookie": "^2.2.0",
    "lodash": "^4.17.10",
    "moment": "^2.22.1",
    "popper.js": "^1.14.3",
    "react": "^16.3.2",
    "react-dom": "^16.3.2",
    "react-loadable": "^5.4.0",
    "react-modal": "^3.4.4",
    "react-redux": "^5.0.7",
    "react-router": "^4.2.0",
    "react-router-dom": "^4.2.2",
    "react-router-redux": "^5.0.0-alpha.9",
    "react-tippy": "^1.2.2",
    "react-toastify": "^4.0.1",
    "redux": "^4.0.0",
    "redux-saga": "^0.16.0"
  },

Ответы [ 2 ]

0 голосов
/ 10 апреля 2019

Просто оставлю это здесь, потому что это может кому-то помочь. Я столкнулся с проблемой при настройке саг для проекта, где саги не запускались, даже если все было настроено и настроено правильно. Консоль тоже не выдавала ошибок. Но реальная проблема заключалась в том, что при определении значений по умолчанию для состояния, в котором я должен был задавать значения по умолчанию для объектов, я просто передавал значение null вместо создания целых объектов со свойствами (ленивый меня).

Так что на самом деле это приводит к ошибкам, когда вы пытаетесь получить доступ к свойствам из этих объектов, но передаете начальное значение как ноль, вы будете пытаться получить доступ к свойствам с нуля - что может испортить проект. И в некоторых случаях он выдает ошибки, а в некоторых - нет. Так что это было причиной того, что сага тоже не работала правильно.

0 голосов
/ 07 мая 2018

Есть две проблемы.

Сначала вам нужно использовать toggleLoginModal из реквизита - так как он обернут в dispatch благодаря connect. Цитировать https://github.com/reactjs/react-redux/blob/master/docs/api.md#connectmapstatetoprops-mapdispatchtoprops-mergeprops-options

[mapDispatchToProps (dispatch, [ownProps]): dispatchProps] (объект или Функция): если передается объект, предполагается, что каждая функция внутри него быть создателем действий Redux. Объект с такими же именами функций, но с каждым создателем действий, включенным в диспетчерский вызов, чтобы они могли будет вызван напрямую, будет добавлен в реквизиты компонента.

Так что в Header.jsx используйте:

handleLoginClick = () => {
    this.props.toggleLoginModal(true);
};

Вторая проблема заключается в том, что вы используете toggleLoginModalReturn как thunk без промежуточного программного обеспечения thunk. Добавьте redux-thunk в свой список промежуточных программ.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...