1

I'm working with react v0.14.3, redux v3.0.5, react-redux v4.02 and immutable v3.7.6. Im trying to wire together the redux store with a react component using react-redux but I cant seem to get the store data to be passed down to the components. My console is clean of errors and In my redux-devtools I see the whole state tree. In my index.js component I have the Provider component setup correctly. Im hoping its a simple error I may have overlooked.

Store & Provider

import { createStore, applyMiddleware, compose } from 'redux';
import thunkMiddleware from 'redux-thunk';
import rootReducer from './../reducers/rootReducer.js';
import DevToolsx from './../components/DevTools/Devtools.jsx';

// var createStoreWithMiddleware = applyMiddleware(thunkMiddleware)(createStore);

var finalCreateStore = compose(
  applyMiddleware(thunkMiddleware),
  // window.devToolsExtension ? window.devToolsExtension() : f => f
  DevToolsx.instrument()
)(createStore);

export default function configureStore(initialState) {
  var store = finalCreateStore(rootReducer, initialState);
  return store;
}
//index.js
var store = configureStore();

render(
  (
    <Provider store={store}>
      <Router history={history} >
        ...
      </Router>
    </Provider>

    ),document.getElementById('app'));

Reducer

//imports are in my codebase

var sample = I.List.of(
  I.Map({
    sneakerImg: 'someLinkToSneakerImg1',
    sneakerName: 'Air Jordane 1',
    price: 120,
    condition: 10,
    size: 12,
    reRelease: true,
    quantity: 1
  })
);

export function dashShoppingCartReducer (state = sample, action ) {
  switch (action.type) {

    case CHECKOUT:
      return handleCheckout(state, action.cartPayload);

    case REMOVE_SNEAKER_FROM_CART:
      return handleRemoveSneakerFromCart(state, action.sneakerToRemove);

    case RECEIVE_SNEAKERS_IN_CART:
      return handleReceiveSneakersInCart(state, action.cartSneakers);

    default:
      return state;
  }
}

rootReducer.js

//imports are in my codebase

const rootReducer = combineReducers({
  landing: landingReducer,
  dashboard: dashboardReducer,
  listings: listingsReducer,
});

export default rootReducer;

dashboardReducer

//imports are in my codebase

export const dashboardReducer = combineReducers({
  userSneakers: dashSharedReducer,
  shoppingCart: dashShoppingCartReducer,
});

DashCart.jsx

import React from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import DashCartTable from './DashCartTable.jsx';
import * as DashCartActions from './../../actionCreators/Dashboard/DashShoppingCart.js';
function DashCart (props) {

  var checkOut = () => props.actions.checkout(props.cartSneakers);

  return (
    <div className="DashCart">
      <DashCartTable cartSneakers={props.cartSneakers} actions={props.actions}></DashCartTable>
      <button onClick={checkOut} className="checkout btn btn-default">CheckOut</button>
    </div>
  );
}

function mapStateToProps(state) {
  return {
    cartSneakers: state.dashboard.shoppingCart
  }
}

function mapDispatchToProps(dispatch) {
  return {
    actions: bindActionCreators(DashCartActions, dispatch)
  }
}

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(DashCart);

DashCartTable.jsx

import React from 'react';
function DashCartItem (props) {

  var remove = () =>  props.actions.removeSneakerFromCart(props.key);

  return (
    <div className="DashCartItem">
      <div className="pull-left">
        <img className="itemImg"src="./../../../assets/images/creator.jpg" />
      </div>
      <div className="content pull-left">
        <h3 className="itemTitle">{props.sneaker.sneakerName}</h3>
        <p>Condition: {props.sneaker.condition}</p>
        <p>Size: {props.sneaker.size}</p>
        <p>Re-release: {props.sneaker.reRelease}</p>
      </div>
      <div className="content pull-right">
        <p>${props.sneaker.price}</p>
        <p>Quantity: {props.sneaker.quantity}</p>
        <button onClick={remove} className="btn btn-default">Remove</button>
      </div>
    </div>
  );
}

export default DashCartItem;

DashCartItem.jsx

import React from 'react';
import DashCartItem from './DashCartItem.jsx';
function DashCartTable (props) {

  var DashCartItemsList = props.cartSneakers.map((sneaker, key) => {
    <DashCartItem sneaker={sneaker} key={key} remove={props.removeSneakerFromCart}></DashCartItem>
  });

  return (
    <div className="DashCartTable">
      {DashCartItemsList}
    </div>
  );
}

export default DashCartTable;
6
  • Please also include your store and reducer code. Commented Dec 28, 2015 at 22:22
  • okay ill do that now Commented Dec 28, 2015 at 22:23
  • Also the file that defines configureStore. It's important to see how the state is structured. Commented Dec 28, 2015 at 22:31
  • One more thing: the rootReducer file. Commented Dec 28, 2015 at 22:33
  • @DavidWalsh The odd thing is that the checkout actionCreator get dispatched if I click checkout with the payload from the store state tree. But the components don't get populated. Commented Dec 28, 2015 at 22:33

1 Answer 1

2

The problem definitely lies here:

function mapStateToProps(state) {
  return {
    cartSneakers: state.dashboard.shoppingCart
  }
}

Assuming dashShoppingCartReducer lives in dashboardReducer.js, that shoppingCart key does not exist. Either remove the shoppingCart key from that line above, or add a shoppingCart key to your state.

Update

Disregard the above. I didn't realise you were using nested combineReducers.

I now think the problem lies with DashCartItem. Since you're using ImmutableJS, you should be accessing the fields with props.sneaker.get('sneakerName') instead of props.sneaker.sneakerName.

Update 2

Be careful how you use arrow functions. They only have an implicit return if you don't use braces.

The following won't work:

var DashCartItemsList = props.cartSneakers.map((sneaker, key) => {
  <DashCartItem sneaker={sneaker} key={key} remove={props.removeSneakerFromCart}></DashCartItem>
});

Instead, change it to:

var DashCartItemsList = props.cartSneakers.map((sneaker, key) => {
  return <DashCartItem sneaker={sneaker} key={key} remove={props.removeSneakerFromCart}></DashCartItem>
});

Or to utilise the implicit return, use parentheses instead.

var DashCartItemsList = props.cartSneakers.map((sneaker, key) => (
  <DashCartItem sneaker={sneaker} key={key} remove={props.removeSneakerFromCart}></DashCartItem>
));
Sign up to request clarification or add additional context in comments.

10 Comments

The dashShoppingCartReducer does live inside the dashboardReducer, In the devtools it shows you the state tree and it has the following ``` state:{ dashboard:{ shoppingCart:{ 0: {..} } } } ``` Im just not sure why the component doesn't receive it.
Where is that shoppingCart defined in your code? It's missing from the sample object.
it is defined inside the dashboard combineReducer I used combine reducer, once to combine all the dashboard reducers, and a scond time to combine it with all the app reducers. inside the first combine reducer there is the shoppingCart.
OK. I now understand your reducer setup better. I now think the problem has to do with how you're using ImmutableJS. I've updated my answer accordingly.
Try installing React dev tools. Check that each component has the properties you expect. That way you can narrow down the problem. github.com/facebook/react-devtools
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.