AnApprentice
AnApprentice

Reputation: 110960

Why isn't my Redux state structured correctly?

In CatsPage.js's mapStateToProps function, the output for console.log(state) is displaying:

Object
    Cats (Object)
        Cats (Array)

When the nesting I want is:

Object
    Cats (Array)

What am I doing wrong?

setup.js

import cats from '../reducers/catReducer';

let store;

const initStore = ({onRehydrationComplete}) => {

  store = createStore(
    combineReducers({
      ...reactDeviseReducers,
      form: formReducer,
      router: routerReducer,
      apollo: apolloClient.reducer(),
      cats
    }),
    {},
    compose(
      applyMiddleware(
        thunk,
        routerMiddleware(history),
        apolloClient.middleware()
      ),
      autoRehydrate(),
      window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
    )
  );

  persistStore(store, {
    blacklist: [
      'form'
    ]
  }, onRehydrationComplete);

  return store;
};

catReducer.js

import * as types from '../actions/actionTypes';

const initialState = {
  cats: []
}

export default function catReducer(state = initialState.cats, action) {
  return state
}

CatsPage.js

import React from 'react';
import PropTypes from 'prop-types';
import {connect} from 'react-redux';
import CatList from './CatList';
import {loadCats} from '../../actions/catActions';

class CatsPage extends React.Component {
  componentDidMount() {
    console.log('CatsPage: componentDidMount');
    this.props.dispatch(loadCats())
  }
  render() {
    return (
      <div>
        <h1>Cats</h1>
        <div>
          <CatList cats={this.props.cats} />
        </div>
      </div>
    );
  }
}

CatsPage.propTypes = {
  cats: PropTypes.array.isRequired
};

function mapStateToProps(state, ownProps) {

  console.log('mapStateToProps')
  console.log(state)

  return {
    cats: state.cats
    //cats: [{id:1, name: "Maru"}]
  };
}

export default connect(mapStateToProps)(CatsPage);

Upvotes: 1

Views: 39

Answers (2)

Andrew Li
Andrew Li

Reputation: 57964

The way you're structuring your initial state is causing the unwanted nesting you see. Instead of using an object as initial state, just use an array to get rid of the nesting:

const initialState = [];

And set initial state of the reducer like so:

function catReducer(state = initialState, action) {
    ...
}

Since catReducer only controls its slice of state, it only controls the array of cats. Thus, it's initial slice of state should just be the array, not an object holding an array; that ruins the desired structure.

Upvotes: 2

basarat
basarat

Reputation: 275867

What am I doing wrong?

The following code segment is wrong

export default function catReducer(state = initialState.cats, action) {
  return state
}

state = initialState.cats is setting state to an array. If you want it to be an object you should do state = initialState.

Upvotes: 0

Related Questions