Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

redux - reducer state is blank

I am trying to replicate something similar to the TodoList example in the the redux docs' basic example. The second reducer receives an array - styleItems = [{... ... }, {... ...}] - and then calls the first function to act on each of the individual objects.

I provide an initialState to the app container via the following, as shown in containers/app.js. However, the state passed to the styleItems reducer seems to be a blank array - each and every time.

However, react renders the UI based on the initial config, and react dev-tools shows the state structure as expected. Is the redux store somehow seeing the same thing as react?

containers/app.js

function starterInfo(state) {
    return {

        // The ID of this particular object
        id: 12345,

        // Various keys and theri css values
        styleItems: [
            {
                pk: 31,
                order: 1,
                label: 'Caption text color',
                css_identifier: '.caption-text',
                css_attribute: 'color',
                css_value: '#FFFFFF'
            },
            {
                pk:23,
                order: 2,
                label: 'Caption link color',
                css_identifier: '.caption-link',
                css_attribute: 'color',
                css_value: '#FEFEFE'
            }
        ],

        // Network state info
        currently_fetching: false,
        currently_posting: false
    }
}

export default connect(starterInfo)(App)

reducers/index.js

// This handles a single styleItem object within the array
function change_css(state = {}, action){
    switch (action.type){
        case actions.CHANGE_CSS:

            if (state.order !== action.order){
                return state
            }

            return {
                ...state,
                css_value
            }

        default:
            return state
    }
}

// This handles the styles array in the global state
function styleItems(state = [], action){
    switch(action.type){       
        case actions.CHANGE_CSS:

            const foobar = state.map(styleItem =>
                change_css(styleItem, action)
                )            

            return foobar

        default:
            return state
    }
}
like image 262
snakesNbronies Avatar asked Jan 18 '16 16:01

snakesNbronies


People also ask

Why is Redux state undefined?

When Redux initializes it dispatches a "dummy" action to fill the state. So your counter reducer was called with state equal to undefined . This is exactly the case that "activates" the default argument. Therefore, state is now 0 as per the default state value ( state = 0 ).

How do you set state in reducer?

Setup Reducer Updater Functions To use the reducer function along with React we need to call it with one of the constants we setup, and then pass it into setState . increment = () => { this. setState( reducer({ type: INCREMENT, }) ); }; decrement = () => { this. setState( reducer({ type: DECREMENT, }) ); };

How do I declare a state in Redux?

The state that we use inside redux as a store can only be modified with the help of the actions. But, this state must be specified somewhere first to use it. We prefer to declare our initial state at the reducer files. Then we use that reducer in the store and provide that store use inside the whole application.

Why is Redux state read only?

As mentioned above, state in Redux is read-only. This helps you restrict any part of the view or any network calls to write/update the state directly. Instead, if anyone wants to change the state of the application, then they'll need to express their intention of doing so by emitting or dispatching an action.


1 Answers

The short answer is that you're not passing the initial state quite right. The first argument to the connect function for the React Redux bindings is mapStateToProps. The point of this function is to take the state that already exists in your app and map it to props for your component. What you're doing in your starterInfo function is kind of just hard-coding what the state is for your component. Because you're returning a plain object React doesn't really know the difference so it works just fine, but Redux doesn't yet know about your app state.

Instead, what you should do is provide your initial state directly to the reducers, like this:

const intialStyleItemsState = [
    {
        pk: 31,
        order: 1,
        label: 'Caption text color',
        css_identifier: '.caption-text',
        css_attribute: 'color',
        css_value: '#FFFFFF'
    },
    {
        pk:23,
        order: 2,
        label: 'Caption link color',
        css_identifier: '.caption-link',
        css_attribute: 'color',
        css_value: '#FEFEFE'
    }
];

function styleItems(state = intialStyleItemsState, action){ ...

And eventually, because you're splitting your reducers up you'll need to combine them back together again with Redux's combineReducers utility, provide that root reducer to your store and go from there.

like image 197
Nick Ball Avatar answered Oct 08 '22 01:10

Nick Ball