Redux Reducer在客户端的next.js返回未定义

时间:2019-01-12 11:45:54

标签: reactjs redux next.js

我目前正在与Redux一起使用Nextjs进行项目开发。我有2个减速器,由Redux的combineReducer()组合而成。当我注销时,第一个在服务器端返回一个值,但在客户端未定义。我的第一个猜测是它与导入有关,我输入的路径不正确,但是我检查了一下,一切似乎都很好。后来我检查了输入文件index.js,并尝试在其他文件中注销此reducer的值,但是一切正常。我不知道是什么原因导致了这个问题。

重要提示:第二个reducer在客户端和服务器端都能正常工作)

首先,这是我的项目结构(我相信这是相关的。如果没有,我将编辑问题)

+-- 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

所以这是我的代码,以防万一我做错了事

root-controllers / 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;
  }
};

components / Header / controllers / 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;
  }
};

store / 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,
  },
};

store / 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 / 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;
};

预先感谢您对此进行调查。如果您还需要与redux相关联的代码,我很乐意提供

0 个答案:

没有答案