Редуктор Redux возвращает неопределенное значение на стороне клиента next.js - PullRequest
0 голосов
/ 12 января 2019

В настоящее время я работаю над проектом с 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;
};

Заранее спасибо за внимание. Если вам нужно больше кода, связанного с избыточностью, я с радостью предоставлю

...