2015-12-05 8 views
17

Mój kod działa poprawnie, ale mam irytujący problem za każdym razem, gdy popełniam błąd kodowania i otrzymuję błąd runtime. Na przykład, w jednym z moich stron JSX zrobiłem Date() zamiast new Date() i zamiast zgłaszania rzeczywisty błąd, mam ...React + Redux-router = Uncaught Error: Oczekiwano, że reduktor stanie się funkcją

Uncaught Error: Expected the reducer to be a function. 

Każdy błąd robię prawie zawsze pojawia się, jak ten. Jest on zgłaszany od createStore.js, który znajduje się poniżej w moim kodzie configureStore.jsx.

Czy istnieje sposób, w jaki mogę uzyskać lepsze raporty o błędach, które pomogą mi zidentyfikować prawdziwy problem? Każda pomoc lub pomysły są mile widziane !!!

Oto mój setup dla odniesienia ....

main.jsx

import React from 'react'; 
import ReactDOM from 'react-dom'; 
import { Provider } from 'react-redux'; 
import { ReduxRouter } from 'redux-router'; 
import configureStore from './store/configureStore' 
import routes from './routes'; 

const rootEl = document.getElementById('app-container'); 

const store = configureStore(); 

ReactDOM.render(
    <div> 
     <Provider store={store}> 
      <ReduxRouter routes={routes} /> 
     </Provider> 
    </div> 
    , rootEl 
); 

configureStore.jsx

import { createHashHistory } from 'history'; 
import { applyMiddleware, createStore, compose } from 'redux'; 
import { reduxReactRouter } from 'redux-router'; 

import thunk from 'redux-thunk'; 
import promiseMiddleware from 'redux-promise-middleware'; 

import rootReducer from '../reducers/rootReducer'; 
import routes from '../routes'; 

export default function configureStore(initialState = {}) { 

    const history = createHashHistory(); 

    const middlewares = [ 
     thunk, 
     promiseMiddleware({ 
      promiseTypeSuffixes: ['PENDING','SUCCESS','ERROR'] 
     }) 
    ]; 

    const toolChain = [ 
     applyMiddleware(...middlewares), 
     reduxReactRouter({ 
      routes, 
      history 
     }) 
    ]; 

    const store = compose(...toolChain)(createStore)(rootReducer, initialState); 

    if (module.hot) { 
     module.hot.accept('../reducers',() => { 
      const nextRootReducer = require('../reducers/rootReducer'); 
      store.replaceReducer(nextRootReducer); 
     }); 
    } 
    return store; 
} 

rootReducer.jsx

import { combineReducers } from 'redux'; 
import { routerStateReducer } from 'redux-router'; 
import siteReducer from './siteReducer'; 

const rootReducer = combineReducers({ 
    router: routerStateReducer, 
    sites: siteReducer 
}); 
export default rootReducer; 

siteReducer.jsx

import {GET_SITES} from '../actions/siteActions'; 

const defaultState = { 
    isPending: null, 
    isSuccess: null, 
    isError: null, 
    error: null, 
    data: null 
}; 

export default function siteReducer(state = defaultState, action) { 

    switch (action.type) { 
     case `${GET_SITES}_PENDING`: 
      return { 
       ...defaultState, 
       isPending: true 
      }; 
     case `${GET_SITES}_SUCCESS`: 
      return { 
       ...defaultState, 
       isSuccess: true, 
       error: false, 
       data: action.payload 
      }; 
     case `${GET_SITES}_ERROR`: 
      return { 
       ...defaultState, 
       isError: true, 
       error: action.payload 
      }; 
     default: 
      return state; 
    } 
} 
+1

Próbowałem zainstalować wszystkie pliki lokalnie, a dla mnie wydaje się, że działa poprawnie. Czy próbowałeś komentować część "hot-reload"? –

+0

Czy znalazłeś jakieś rozwiązanie? –

+0

[create-react-app] (https://github.com/facebookincubator/create-react-app) jest całkiem niezły w zgłaszaniu poprawnego błędu. Możesz stworzyć nowy projekt, wyrzucić i zobaczyć, co robią. –

Odpowiedz

4

Zastosowanie export const variable_name zamiast const variable_name gdy chcesz wyeksportować zmienną.

Dla ex: rootReducer.jsx należy ponownie zapisać jako

import { combineReducers } from 'redux'; 
import { routerStateReducer } from 'redux-router'; 
import siteReducer from './siteReducer'; 

export const rootReducer = combineReducers({ 
router: routerStateReducer, 
sites: siteReducer 
}); 
export default rootReducer; 

Uwaga dodatkowa specyfikującego eksport z const rootReducer

+1

dlaczego wyeksportowałeś go jako eksport nazwany? to niczego nie rozwiąże – ZekeDroid

+0

Cóż !! to działało dla mnie. –

+0

Zmienia to tylko sposób późniejszego importowania reduktorów.Zauważ, jak w tworzeniu sklepu OP importuje 'rootReducer' używając nienazwanego importu, co oznacza domyślnie. Dodanie nazwanego eksportu niestety nie rozwiąże niczego. – ZekeDroid

11

Zmień następujący wiersz:

const nextRootReducer = require('../reducers/rootReducer'); 

Do:

const nextRootReducer = require('../reducers/rootReducer').default; 
+1

Lub użyj https://www.npmjs.com/package/babel-plugin-add-module-exports :) – rcsole

0

Mój problem polegał na tym, że importowałem Store ze ścieżki głównej reduktora, a nie z rzeczywistego katalogu głównego sklepu (z devtools na oknie i reduktorem root, komponowanie middleware, itp.).

import Store from '../../../src/state/Store/reducer';

zmieniona na

import Store from '../../../src/state/Store';

Powiązane problemy