Суммирование:
Я пытаюсь объединить Next.js
+ Redux-saga(+combineReducer)
. приложение успешно отображает страницу, но props.store
кажется недоступным и не отражает результат избыточных действий .
Я взял примеры из этих ресурсов (вероятно, единственные примеры реального кода, которые я нашел в Интернете):
Next.js
официальный github: https://github.com/zeit/next.js/tree/canary/examples/with-redux-saga
Пример Codesandbox next-redux-saga: https://codesandbox.io/s/y16j84949?from-embed
Сначала я подумал, что моя инициализация неверна, поэтому я попробовал другие аргументы с withReduxSaga
, например withReduxSaga({ async: true})
, withReduxSaga()
, withReduxSaga
, и ни один из них не сработал.
Во-вторых, я подумал, что, возможно, компонент должен быть предоставлен в форме class , а не в форме function , поэтому я переключил и документ, и компонент таким же образом, но все еще не работает.
мой полный код доступен здесь, если требуется детальная проверка:
https://codesandbox.io/s/next-redux-saga-5twxj
фактические коды:
редуктор комбинируется через combineReducer
, и с использованием моего Enhancer
// custom enhancer - util.js
const enhanceAll = (head, targets) => targets.reduce((ac, cv) => cv(ac), head);
// reducer is combined via combineReducers - in root reducer
const rootReducer = combineReducers({
count: countReducer,
});
// store/index.js
import { applyMiddleware, createStore } from 'redux';
import createSagaMiddleware from 'redux-saga';
import rootReducer, { exampleInitialState } from './reducers';
import rootSaga from './sagas';
const bindMiddleware = middleware => {
if (process.env.NODE_ENV !== 'production') {
const { composeWithDevTools } = require('redux-devtools-extension');
return composeWithDevTools(applyMiddleware(...middleware));
}
return applyMiddleware(...middleware);
};
function configureStore(initialState = exampleInitialState) {
const sagaMiddleware = createSagaMiddleware();
const store = createStore(
rootReducer,
initialState,
bindMiddleware([sagaMiddleware]),
);
store.sagaTask = sagaMiddleware.run(rootSaga);
return store;
}
export default configureStore;
// providing the redux-saga store
// pages/_app.js
import React from 'react';
import App, { Container } from 'next/app';
import { Provider } from 'react-redux';
import withRedux from 'next-redux-wrapper';
import withReduxSaga from 'next-redux-saga';
import { enhanceAll } from '../util';
import createStore from '../store';
import '../styles/common.scss';
class MyApp extends App {
static async getInitialProps({ Component, ctx }) {
let pageProps = {};
if (Component.getInitialProps) {
pageProps = await Component.getInitialProps({ ctx });
}
return { pageProps };
}
render() {
const { Component, pageProps, store } = this.props;
return (
<Container>
<Provider store={store}>
<Component {...pageProps} />
</Provider>
</Container>
);
}
}
const enhancers = [withRedux(createStore), withReduxSaga];
const enhanced = enhanceAll(MyApp, enhancers);
export default enhanced;
// custom component using redux-saga
// omitted its directory because it is irrelevant to the problem.
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { enhanceAll } from '../util';
import { addNum, subNum } from '../store/actions';
class SagaComponent extends Component {
render() {
const { dispatch, store } = this.props;
return (
<div>
<span>{JSON.stringify(this.props)}</span>
<button onClick={() => dispatch(addNum(1))}>add count</button>
<button onClick={() => dispatch(subNum(1))}>sub count</button>
</div>
);
}
}
const enhancers = [connect(state => state)];
const enhanced = enhanceAll(SagaComponent, enhancers);
export default enhanced;
создатель действий и saga не содержат ничего особенного, следует обычному соглашению.
ошибка:
Из того, что я вижу из redux webdev chrome extension , само действие запускается правильно, но redux-saga
не отражает действие. Кроме того, хранилище резервов не работает должным образом, значения внутри хранилище резервов не изменяются вообще.