skip to Main Content

I am new to React and I am building a online store website. I use context API to store my products list that fetch from database. But "Objects are not valid as a React child" error will appear when I try to set it as object. Below are my codes,

ProductsContext.jsx

import { createContext,useContext,useEffect,useState } from "react";

export const ProductsContext = createContext(null);

export const Products = () => {
    return useContext(ProductsContext)
  }
  
export const ProductsProvider = ({children}) => {
    const [contextProducts, setProducts] = useState()
    

    const contextValue = { contextProducts, setProducts};

    return (
      <ProductsContext.Provider value={contextValue} displayName="Products Context"> 
        {children}
      </ProductsContext.Provider>
    )
}

api.js

export async function GETProductsListByCat(cat) {

    const command = new QueryCommand({
        TableName: 'mytable',
        IndexName: 'category',
        KeyConditionExpression: 'cat = :cat',
        ExpressionAttributeValues: {
            ':cat': cat,
        },
    });
    try {
        const response = await docClient.send(command);
        const products_awsFormat = response.Items;
        const products_transformedData = {};
        for (const item of products_awsFormat) {
            products_transformedData[item.productId] = {
                ...item,
            };
        }
        console.log(products_transformedData); //see below picture
        return products_transformedData;
    } catch (e) {}

}

Products.jsx

import { useState, useEffect, useContext } from 'react';
import { ProductsContext } from '../../contextAPI/ProductsContext';
import { GETProductsListByCat } from "../../src/server/api"

function Products() {
    const { contextProducts, setProducts } = useContext(ProductsContext);
    useEffect(() => {

        if (!contextProducts||contextProducts.length ===0) {
            async function fetchData() {
                try {
                    const productList = await GETProductsListByCat("cate");
                    setProducts(productList);
                } catch (error) {
                    console.error('Error fetching data:', error);
                }
            }
            fetchData();
        }
        }, []);


    return (
           ...
            {contextProducts&&
                <div>
                  {Object.keys(contextProducts).map((cookieId) => (
                        <a href={`cookies/${cookieId}`} className='product-container' key={cookieId}>
                            <img src="products/01/thumbnail.jpg" alt="product" className='product-thumbnail'></img>
                            <div className='label'> {contextProducts[cookieId].name}</div>
                            <div className='label'>${contextProducts[cookieId].price}/100g</div>
                        </a>
                    ))}
                </div>
            }
    );
}

export default Products;

enter image description here
I am getting "Objects are not valid as a React child (found: object with keys {}). If you meant to render a collection of children, use an array instead." with the current code.

2

Answers


  1. You have not initialized contextProducts with an initial value. This can cause issues when contextProducts is used before data is fetched. It’s generally a good practice to initialize state with a default value that matches the expected data type. Since you’re dealing with a list of products, you might want to initialize it as an empty object:

    const [contextProducts, setProducts] = useState({});
    
    Login or Signup to reply.
  2. Inside Products.jsx

    you should not return object what you did is you trying to return object instead of jsx markup

    Don’t:
    return ({})

    Do:

    function Products() {
    const { contextProducts, setProducts } =useContext(ProductsContext);
    useEffect(() => {
    
        if (!contextProducts||contextProducts.length ===0) {
            async function fetchData() {
                try {
                    const productList = await GETProductsListByCat("cate");
                    setProducts(productList);
                } catch (error) {
                    console.error('Error fetching data:', error);
                }
            }
            fetchData();
        }
        }, []);
    
    
    return (contextProducts&&
                <div>
                  {Object.keys(contextProducts).map((cookieId) => (
                        <a href={`cookies/${cookieId}`} className='product-container' key={cookieId}>
                            <img src="products/01/thumbnail.jpg" alt="product" className='product-thumbnail'></img>
                            <div className='label'> {contextProducts[cookieId].name}</div>
                            <div className='label'>${contextProducts[cookieId].price}/100g</div>
                        </a>
                    ))}
                </div>||null
            
    );
    

    }

    export default Products;

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search