react-redux not connecting store to react component

- 1 answer

Ad

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;
Ad

Answer

Ad

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>
));
Ad
source: stackoverflow.com
Ad