简体   繁体   中英

React redux - store isn't loaded but no errors

I am following the code example from Learning React book. It is about react redux and react router used for single page app.

Here is the link to my project where I mimic the example above. You can clone it and run with npm install and npm run dev . (Note: project also has back end code but it is irrelevant. Question is only about front end part where I use static data file.)

I can successfully run the example locally, but when I run my project I see my store being empty when it comes to load ui components. I don't get any compile or console errors, and I see other parts of the app working fine. I spent lots of time debugging store creation code but I can't figure out why it doesn't work. Please help to find the reason.

Here are my findings:

There are two url available in my project: / and /cars . The /cars url reads data file directly and it does output all the data correctly.

The root url suppose to do the same by utilizing redux store. However the data array used by ui component comes empty. I guess there is something wrong with the code for store creation (below), although I precisely mimicked the code example. There is literally only one change that I made which is carsReducer , and I coded it exactly as other reducers in the example.

I also noticed that localStorage isn't being populated in the console, but it doesn't give much clue.

src/main/resources/static/js/store/index.js

const storeFactory = (initialState=stateData) =>
    applyMiddleware(logger, saver)(createStore)(
        combineReducers({carsReducer}),
        (localStorage['redux-store']) ?
            JSON.parse(localStorage['redux-store']) :
            initialState
    )

Try having a constructor and initialize your Store on /car-saver/src/main/resources/static/js/index.js

constructor(props) {
   super(props);
   this.store = configureStore();
}

and pass it to your <Provider store={this.store}>

I can recommend you some fixes:

js/index.js — Main provider file

import React from 'react'
import { render } from 'react-dom'
import { Provider } from 'react-redux'
import { HashRouter } from 'react-router-dom'
import App from './components/App'
import 'bootstrap/dist/css/bootstrap.min.css'
import store from './store'

window.React = React
window.store = store

render(
    <Provider store={store}>
        <HashRouter>
            <App />
        </HashRouter>
    </Provider>,
    document.getElementById('react-container')
)

js/store/index.js — Store file

import { createStore, combineReducers, applyMiddleware } from 'redux'
import {carsReducer} from './reducers'
import stateData from '../../data/cars.json'

let console = window.console

const logger = store => next => action => {
    let result
    console.groupCollapsed("dispatching", action.type)
    console.log('prev state', store.getState())
    console.log('action', action)
    result = next(action)
    console.log('next state', store.getState())
    console.groupEnd()
    return result
}

const saver = store => next => action => {
    let result = next(action)
    localStorage['redux-store'] = JSON.stringify(store.getState())
    return result
}

const initialState = localStorage['redux-store'] || stateData

const store = createStore(
    combineReducers({...carsReducer}),
    stateData,
    applyMiddleware(logger, saver)
)

export default store

CarsTable.js — And some fixes to cars list JSX structure

import PropTypes from 'prop-types'
import CarRow from './CarRow'

const CarsTable = ({cars = []}) =>
    <div>
        {(cars.length === 0) ?
            <p>Cars list is empty.</p> :
            <table className="table">
                <thead>
                <tr>
                    <th>Ad name</th>
                    <th>Price</th>
                    <th>Location</th>
                    <th>Odometer</th>
                    <th>Condition</th>
                </tr>
                </thead>
                <tbody>
                {
                    cars.map((car, i) =>
                        <CarRow key={i} car={car} />
                    )
                }
                </tbody>
            </table>
        }
    </div>

CarsTable.propTypes = {
    cars: PropTypes.array
}

export default CarsTable

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM