skip to Main Content

I have a working app and no problems with props except when I have to filter those variables before sending them to a child component. Here’s my parent component:

import React, { useState, useEffect } from 'react';
import { useParams } from 'react-router-dom';
import ItemDetail from './ItemDetail';

const ItemDetailContainer = () => {
    const { itemId } = useParams();
    const [catData, setCatData] = useState([]);
    const [prodData, setProdData] = useState([]);

    const getData = () => {
        fetch('/data.json', {
            headers: {
                'Content-Type': 'application/json',
                Accept: 'application/json',
            },
        })
            .then(function (response) {
                return response.json();
            })
            .then(function (myJson) {
                setProdData(myJson['products'].find((c) => c.id == itemId));
                setCatData(myJson['categories'].find((c) => c.catId == prodData.catId));
            });
    };
    useEffect(() => {
        getData();
    }, []);

    if (prodData === null || catData === null || prodData === undefined || catData === undefined) {
        return null;
    }

    return <ItemDetail prodInfo={prodData} catInfo={catData} />;
};

export default ItemDetailContainer;

When I receive those props in ItemDetail I get a blank object:

Props as soon the page loads

But when I go back to my code and hit save on ItemDetailContainer (parent component), I get the content from the childs’ props:

Props after I save the parent component

I’ve tried using useEffect with and without dependencies, timeouts, intervals, returning from a function… don’t really know what else to try. Any clues?

BTW, I’m only displaying one of the props onto the console. That’s why they are the same (dunno why they always appear twice tho).

Thanks a lot in advance!!!

2

Answers


  1. useState saves your values to the next render, so when you call find(c.catId === prodData.catId), your prodData.catId is still the old one (since React hasn’t re-render yet).

    The solution is pretty straightforward, just don’t use that state value and use what you’ve got from your json instead, somewhat like:

        .then(function (myJson) {
          const newProductData = myJson['products'].find((c) => c.id == itemId
          setProdData(newProductData);
          setCatData(myJson['categories'].find((c) => c.catId == newProductData.catId));
        });
    

    Another fyi: your logs appear twice because of React’s Strict Mode. It will run your hooks twice in development environment to make sure everything is working as expected (and show warnings if it’s not). You can turn that off but it’s not recommended.

    Login or Signup to reply.
  2. It might be good for this matter.

     .then(function (myJson) {
        const tmp_prodData = myJson['products'].find((c) => c.id == itemId)
        setProdData(tmp_prodData);
        setCatData(myJson['categories'].find((c) => c.catId == tmp_prodData.catId));
     });
    
    ...
    
    useEffect(() => {
       ...
    }, [prodData, catData])
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search