2015-12-05 10 views
17

Il mio codice funziona correttamente, ma ho un fastidioso problema ogni volta che commetto un errore di codifica e ottengo un errore di runtime. Per esempio, in una delle mie pagine JSX ho fatto Date() invece di new Date() e invece di riportare l'errore effettivo, ho avuto ...React + Redux-router = Errore non rilevato: Il riduttore dovrebbe essere una funzione

Uncaught Error: Expected the reducer to be a function. 

Qualsiasi errore che faccio quasi sempre si presenta come questo. Viene segnalato da createStore.js, che si trova nel mio codice configureStore.jsx di seguito.

C'è un modo per ottenere una segnalazione degli errori migliore che mi aiuti a identificare il problema reale? Qualsiasi aiuto o idee sono molto apprezzati !!!

Ecco la mia messa a punto di riferimento ....

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

Ho provato a installare tutti i file in locale, e per me sembra funzionare bene. Hai provato a commentare la parte hot-reload? –

+0

Hai trovato qualche soluzione? –

+0

[create-react-app] (https://github.com/facebookincubator/create-react-app) è abbastanza bravo a segnalare l'errore corretto. Puoi creare un nuovo progetto, espellere e vedere cosa stanno facendo. –

risposta

4

Uso export const variable_name invece di const variable_name ogni volta che si desidera esportare quella variabile.

Per esempio: rootReducer.jsx dovrebbe essere riscritto come

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

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

Nota l'identificatore di esportazione in più con rootReducer const

+1

perché vuoi esportarlo anche come esportazione con nome? questo non risolve nulla – ZekeDroid

+0

Bene !! questo ha funzionato per me. –

+0

Questo modifica solo la modalità di importazione dei riduttori in seguito.Si noti come durante la creazione del negozio l'OP importa il 'rootReducer' usando un'importazione senza nome, ovvero il valore predefinito. Aggiungere l'esportazione nominata non risolverà nulla sfortunatamente. – ZekeDroid

11

modificare la riga seguente:

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

A:

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

Oppure usa https://www.npmjs.com/package/babel-plugin-add-module-exports :) – rcsole

0

Il mio problema era l'importazione di Store dal percorso del riduttore di root piuttosto che l'effettivo root di archivio in bundle (con devtools nella finestra e riduttore di root, middleware in fase di composizione, ecc.).

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

cambiato in

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

Problemi correlati