Ошибка типа проп: Проп `store.subscribe` помечен как обязательный, но его значение равно` undefined`. на _app.js - PullRequest
0 голосов
/ 24 октября 2019

У меня есть существующее приложение React / Redux, которое в данный момент конвертируется в Next.

В файле _app я вызываю функцию asyc getinitialProps, и внутри этого im загружаю реквизиты, которые необходимо передать в App.

_app.js

import React from 'react'
import ReactDOM from 'react-dom'
import createHistory from 'history/createMemoryHistory'
import { syncHistoryWithStore, routerMiddleware } from 'react-router-redux'
import { initializeStore } from '../src/store'
import App from '../pages/index'
import { App as AppModel, User as UserModel } from '../src/models'
import * as Api from '../src/api'
import {makeStore} from '../src/redux/makeStore'
const dotenv = require('dotenv-safe')

// const manifest = require('./../dist/manifest.json')

if (typeof window !== "undefined" && window.ReactIntlLocaleData) {
  Object.keys(window.ReactIntlLocaleData).forEach(lang => {
    addLocaleData(window.ReactIntlLocaleData[lang]);
  });
}

class IndexPage extends React.Component {
  static async getInitialProps(context) {
    global.CONFIG = {
      ...dotenv.config().required,
      ...dotenv.config().parsed,
    }
    global.historyUserConfirmationCallback = undefined

    const history = createHistory({
      getUserConfirmation: (message, callback) =>
        global.historyUserConfirmationCallback(message, callback),
    })

    //see if window will work. Study actions push
    history.listen((location, action) => {
      window.scrollTo(0, 0)
      if (location.pathname !== window.location.pathname) {
        if (action === 'PUSH') {
          window.history.pushState(null, null, location.pathname)
        } else if (action === 'REPLACE') {
          window.history.replaceState(null, null, location.pathname)
        }
      }
    })

    if(process.browser){
    window.onpopstate = e => {
      if (
        history.entries[history.entries.length - 1] !== e.target.location.pathname
      ) {
        history.push(e.target.location.pathname)
      }
    }
  }
  function getWindowState(){
    if(process.browser){
    return window.INITIAL_STAT
  }
  }

  const store = initializeStore(getWindowState(), {
    history: routerMiddleware(history),
  })

    const loggedInUser = Api.getCookie('token') && Api.getCookie('loggedInUser')
    const loggedInUserLocale =
      Api.getCookie('token') && Api.getCookie('loggedInUserLocale')
    Api.session({
      baseUrl: 'test',
    })
    if (loggedInUser) {
      Api.session({
        baseUrl: global.CONFIG.APP_API_URL,
        access_token: Api.getCookie('token'),
      }) 
      store.dispatch(AppModel.actions.set('loggedInUser', loggedInUser))
      store.dispatch(
        AppModel.actions.set('loggedInUserLocale', loggedInUserLocale),
      )
      store.dispatch({
        type: `${UserModel.ACTION_LOGIN}_FULFILLED`,
        payload: { data: { username: loggedInUser, locale: loggedInUserLocale } },
      })
    }

    if(process.browser){
    history.push(window.location.pathname)
    syncHistoryWithStore(history, store)
    }
    debugger;

    return {store, history}
  } 
  render() {
    const {store, history} = this.props
    return <App store={store} history={history} location={history.location.pathname} />
  }
}
export default IndexPage

В файле store.js я экспортирую initializeStore следующим образом

  createStore(
    combineReducers(reducers),
    initialState,
    composeWithDevTools(
      applyMiddleware.apply(null, Object.values(defaultMiddlewares)),
    ),
  )

Я хочу передать store в. история пропадает без проблем. Но store - это всегда пустой объект. И это выдает следующую ошибку:

:3000/_next/static/runtime/main.js?ts=1571900711135:16480 Warning: Failed prop type: The prop `store.subscribe` is marked as required in `Connect(PromisedPropsHoc(BusinessProvider))`, but its value is `undefined`.
    in Connect(PromisedPropsHoc(BusinessProvider)) (at ContextHoc.js:53)
    in ContextHOC(Connect(PromisedPropsHoc(BusinessProvider))) (at ContextHoc.js:44)
    in ComponentWithProvider (at _app.js:97)
    in IndexPage
    in Container (created by AppContainer)
    in AppContainer
console.<computed> @ :3000/_next/static/runtime/main.js?ts=1571900711135:16480
:3000/_next/static/development/pages/_app.js?ts=1571900711135:311612 Uncaught TypeError: store.getState is not a function

Я пытался понять, почему это дольше всего. В чем проблема?

import React from 'react'
import PropTypes from 'prop-types'
import { Provider } from 'react-redux'
import { ThemeProvider } from '@material-ui/styles'
import { CssBaseline } from '@material-ui/core'
import { IntlProvider, addLocaleData } from 'react-intl'
import Routes from '../src/components/common/Routes'
import BusinessProvider from '../src/components/common/BusinessProvider'
import translations from '../lang/translations'
import theme from '../theme'
import 'react-image-lightbox/style.css'
import {makeStore} from '../src/redux/makeStore'

const App = ({ loggedInUserLocale, store, location, history, context }) => {
  // Set the default locale
  let locale = 'en';

  // Check whether the logged in user has provided a locale
  if (loggedInUserLocale !== undefined && loggedInUserLocale in translations) {
    locale = loggedInUserLocale;
  }

  console.log("index page store")
  debugger;

  // Replace _ with - as _ is not part of a valid tag https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/getCanonicalLocales#Examples
  const structuredLocale = locale.replace('_', '-');
  const translation = translations[locale]


  addLocaleData(translation.localeData)

  return (
    <ThemeProvider theme={theme}>
      <CssBaseline />
      <Provider store={store} id="App">
        <IntlProvider key={locale} locale={structuredLocale} messages={translation.messages}>
          <BusinessProvider>
            <Routes
              location={location}
              history={history}
              context={context}
            />
          </BusinessProvider>
        </IntlProvider>
      </Provider>
    </ThemeProvider>
  )
}

App.propTypes = {
  // eslint-disable-next-line react/forbid-prop-types
  store: PropTypes.object.isRequired,
  // eslint-disable-next-line react/forbid-prop-types
  history: PropTypes.object,
  // eslint-disable-next-line react/forbid-prop-types
  context: PropTypes.object,
  // eslint-disable-next-line react/forbid-prop-types
  location: PropTypes.string,
}

App.defaultProps = {
  location: '/',
  history: {},
  context: {},
}

export default BusinessProvider.provide()(App)
...