В настоящее время я работаю над проектом с Nextjs с Redux. У меня есть 2 редуктора, которые объединены в Redux combineReducer()
. Первый возвращает значение на стороне сервера, но не определено на стороне клиента, когда я выхожу из системы. Моим первым предположением было то, что это как-то связано с импортом, и что я неправильно набрал путь, но я проверил, и все, кажется, в порядке. Позже я проверил свой входной файл index.js
и попытался записать значение этого редуктора в другие файлы, но все работало хорошо. Я понятия не имею, что вызывает эту проблему.
( Важно: Второй редуктор отлично работает как на стороне клиента, так и на стороне сервера)
Во-первых, это структура моего проекта (я считаю, что это актуально. Если нет, я отредактирую вопрос)
+-- Project
+-- .next
+-- coverage
+-- node_modules
+-- pages
+-- server
+-- src
+-- components
+-- Header
+-- controllers
+-- reducer.js // My second reducer lives here
+-- index.js
+-- root-controllers
+-- reducer.js // My first reducer lives here
+-- index.js
+-- store
+-- defaultState.js // The shape of the application's state
+-- store.js // My store initialise function lives here
+-- combinedReducer.js
+-- index.js
+-- utils
+-- withRedux.js
+-- db.js
+-- theme.js
+-- static
+-- test
Так вот мой код на случай, если я что-то не так сделал
корневые контроллеры / reducer.js
import {
GET_SCROLL_TOP,
GET_BROWSER_INFO,
GET_ENGINE_INFO,
GET_MOBILE_INFO,
GET_OS_INFO,
} from './types';
import { defaultState } from '../store';
export default (state = defaultState.root, action) => {
switch (action.type) {
case GET_SCROLL_TOP:
return {
...state,
scrollTop: action.scrollTop,
};
case GET_BROWSER_INFO:
return {
...state,
browserName: action.browserName,
browserVersion: action.browserVersion,
fullBrowserVersion: action.fullBrowserVersion,
};
case GET_ENGINE_INFO:
return {
...state,
engineName: action.engineName,
engineVersion: action.engineVersion,
};
case GET_MOBILE_INFO:
return {
...state,
mobileVendor: action.mobileVendor,
mobileModel: action.mobileModel,
};
case GET_OS_INFO:
return {
...state,
OSName: action.OSName,
OSVersion: action.OSVersion,
};
default:
return state;
}
};
компоненты / Заголовок / Контроллеры / reducer.js
import { GET_LOGO_SRC, UPDATE_DRAWER_STATE } from './types';
import { defaultState } from '../../../store';
export default (state = defaultState.header, action) => {
switch (action.type) {
case GET_LOGO_SRC:
return {
...state,
logoSrc: action.logoSrc,
};
case UPDATE_DRAWER_STATE:
return {
...state,
drawerOpened: action.isOpened,
};
default:
return state;
}
};
магазин / defaultState.js
export default {
root: {
scrollTop: null,
browserName: null,
browserVersion: null,
fullBrowserVersion: null,
engineName: null,
engineVersion: null,
mobileVendor: null,
mobileModel: null,
OSName: null,
OSVersion: null,
},
header: {
logoSrc: null,
drawerOpened: false,
},
};
магазин / combinedReducer.js
import { combineReducers } from 'redux';
import root from '../root-controllers';
import header from '../components/Header/controllers';
console.log(`Client-side: ${process.browser}, Root: ${typeof root}`); // logs out undefined
export default combineReducers({
root,
header,
});
магазин / store.js
import { createStore, applyMiddleware } from 'redux';
import { composeWithDevTools } from 'redux-devtools-extension';
import thunk from 'redux-thunk';
import combinedReducer from './combinedReducer';
import defaultState from './defaultState';
export default (initialState = defaultState) =>
createStore(combinedReducer, initialState, composeWithDevTools(applyMiddleware(thunk)));
Utils / withRedux.js
import React, { Component } from 'react';
import initialiseStore from '../store';
import getDisplayName from './getDisplayName';
const getStore = initialState => {
if (!process.browser) {
return initialiseStore(initialState);
}
if (!window.__GLOBAL_STORE__) {
window.__GLOBAL_STORE__ = initialiseStore(initialState);
}
return window.__GLOBAL_STORE__;
};
export default App => {
class withRedux extends Component {
static async getInitialProps(appContext) {
const store = getStore();
let appProps = {};
// Provide the store for the pages
appContext.ctx.store = store;
if (typeof App.getInitialProps === 'function') {
appProps = await App.getInitialProps(appContext);
}
return {
...appProps,
initialState: store.getState(),
};
}
store = getStore(this.props.initialState);
render() {
return <App {...this.props} store={this.store} />;
}
}
withRedux.displayName = getDisplayName('withRedux', App);
return withRedux;
};
Заранее спасибо за внимание. Если вам нужно больше кода, связанного с избыточностью, я с радостью предоставлю