user1896446
user1896446

Reputation:

How do you access a variable from mapStateToProps when rendering a React component as a variable?

I have a component that I am trying to access the state from, it looks like this:

const Product = ({add, id, title, image}) => (
  <div className={styles.product} onClick={() => add(id)}>
    <img src={image} alt={title} className={styles.productImage}/>
    {title}
  </div>
);

export default connect(() => ({}), {add})(Product);

I have added MapStateToProps, and now it looks like this:

const Product = ({add, id, title, image}) => (
  <div className={styles.product} onClick={() => add(id)}>
    <img src={image} alt={title} className={styles.productImage}/>
    {title}
    {items.length}
  </div>
);

const mapStateToProps = (state) => {
  return {
    items: state.cart.items,
  };
};

export default connect(mapStateToProps, {add})(Product);

With the code above, I get items is not defined in my console. Yet when removing {items.length} and using React dev tools, I can see that the Product component has access to items. How do I read this items variable from the component?

Upvotes: 2

Views: 1155

Answers (2)

Estus Flask
Estus Flask

Reputation: 222538

mapStateToProps maps state to items prop. It's not a variable but a prop, i.e. props property.

It should be accessed from props, as any other prop:

const Product = ({add, id, title, image, items}) => (
  <div className={styles.product} onClick={() => add(id)}>
    <img src={image} alt={title} className={styles.productImage}/>
    {title}
    {items.length}
  </div>
);

Upvotes: 0

Jack Pilowsky
Jack Pilowsky

Reputation: 2303

This design pattern of destructuring the props parameter this way is very non-standard

const Product = ({add, id, title, image}) => (

I would advise against it because it makes debugging your code hard. You can't console.log your props parameter to try to debug problems. Also, it would be confusing to anyone reading your code because its not something they would have seen.

const Product = (props) => (
   <div className={styles.product} onClick={() => add(props.id)}>
       <img src={props.image} alt={props.title} className={styles.productImage}/>
       {props.title}
       {props.items.length}
   </div>
);

If that doesn't work, something might be wrong in your actions or your reducers. So, you will need start by adding console.logs

const Product = (props) => {
   console.log(props)
   return (
       <div className={styles.product} onClick={() => add(props.id)}>
           <img src={props.image} alt={props.title} className={styles.productImage}/>
           {props.title}
          {props.items.length}
       </div>
   )
};

And

const mapStateToProps = (state) => {
    console.log(state);
    return {
       items: state.cart.items,
    };
};

Upvotes: 1

Related Questions