wUmpage
wUmpage

Reputation: 165

Why is my React Component Not Rendering HTML, but logs correctly?

I'm using Redux to store some API-called data, and in my attempt to render it to screen, I've encountered some issues. Basically, I'm using Redux and Fetch to store all the pulled Products from the Stripe API into a state(prop?) called "products", it's structure looks like this:

{ products:
  product1ID: {
    items: [
      0: {json data from Stripe Product API}
    ]
  },
  product2ID: {
    items: [
      0: {json data from Stripe Product API}
    ]
  },
  etc...
}

This is not the most effective structure, and will likely need to be refactored. However, that's not the issue at the moment, because I can, at least, return the data using console.log(). The real issue is, when an element is inside the .forEach / .map loop, I cannot render my component, or any HTML to the page. Here's my "ProductList" component, that breaks down the structure above:

import React from 'react';
import { connect } from 'react-redux';
import ProductListItem from './Items/ProductListItem'
import selectProducts from '../../../_selectors/products.selector';


const ProductList = (props) => (
  <div>
    <h1>Stripe Product List</h1> //This Prints to Screen
    {
      Object.entries(props.products).forEach(element => {
        return element[1].items.map((product) => {
          //console.log(product)  <-- this logs the json API data correctly! However, nothing prints to screen using HTML elements below!
          return <ProductListItem key={product.id} {...product} /> //This does not display!!! Why?
        })
      })
    }
  </div>
);


const mapStateToProps = (state) => {
  return {
    products: selectProducts(state.productsById)
  };
};

export default connect(mapStateToProps)(ProductList);

And heres the ProductListItem, just in case you need it:

import React from 'react';
import { Link } from 'react-router-dom';

const ProductListItem = ({ id, name, metadata }) => (
  <Link to={`/memberships/${id}`} className="membership red">
    <div className="membership__price">
      <span className="membership__price_price-label">${metadata.price_start}</span>
      <span className="membership__price_mo-label">/mo</span>
    </div>
    <div className="membership__info">
      <h2>{name}</h2>
      <p>{metadata.service_description}</p>
    </div>
  </Link>
);

export default ProductListItem;

So what gives? It logs the correct data, but won't output any HTML. I can't even get a <p> tag to return when I replace the return <ProductListItem key={product.id} {...product} /> line with something simple, like: return <p>test</p>.

I'm fairly new to React and Redux. Any help is appreciated.

Upvotes: 2

Views: 1352

Answers (1)

Trent
Trent

Reputation: 4306

Within JSX you are attempting to return an array of React elements using the Array#forEach method.

The difference between Array#forEach and something like Array#map is the returning value.

  • The Array.forEach() method does not return a value, disregarding the values returned within its callback.

  • The Array.map() method returns an array with the values returned from its callback.


Solution

To fix your issue, you should replace Array#forEach with Array#map:

Object.entries(props.products).forEach

with the following:

Object.entries(props.products).map

Upvotes: 3

Related Questions