Home > Software design >  Undefined state variable when passing state to child components
Undefined state variable when passing state to child components

Time:01-13

I'm working on a like button that when clicked, will update the favourites component with the item that is clicked. I have a state variable declared in my App.js to get this working.

I've passed the state update function into my ProductCard to get get the item object when it's clicked and I then have the state variable passed to my ImageGrid as this is where I want to map the state and display the object.

My issue is that the state is undefined when I pass it into the UserProfile component.

Can anyone tell me what the issue is?

I have made the App.js shorter and removed the array of objects to demonstrate

APP JS

  //State
  const [favourites, setFavourites] = useState([
    {
      type: 'peppermint Latte',
      cafe: 'Nomad',
      location: 'Barcelona',
      price: '$2',
      img: Coffee4,
      index: 4,
    }
  ]);

  // Get items for favourites
  function getItem (item) {
    setFavourites([favourites, item])
    // console.log(favourites)
  }

    useEffect(() => {
      getItem()
    }, [])


  return (
   <>
   
   <Router>
    <Routes>
      <Route path='/' element={<LoginPage/>} />
      <Route path='/profile' element={<UserProfile images={images} getItem={getItem}/>} favourites={favourites} />
    </Routes>
  </Router>
   
   </>
  );
}

export default App;

import React from 'react';
import FavoriteIcon from '@mui/icons-material/Favorite';

const ProductCard = ({images, getItem}) => {



  return (
    <div className="flex flex-wrap mt-44 sm:mt-60 sm:pl-32 sm:pr-32">
      {images.map((item, index) => (
        <div key={item.index} className="w-full sm:w-1/2 lg:w-1/3 p-4">
          <div className="rounded-lg shadow-md bg-neutral-900 text-white">
            <img src={item.img} alt="Product Image" className="w-full h-96 rounded-t-lg" />
            <div className="p-4">
                <div className='flex justify-between'>
                    <h2 className="text-lg font-medium">{item.type}</h2>
                    <h2 className="text-lg font-medium text-yellow-400">{item.location}</h2>
                </div>
            <div className='flex justify-between'>
              <h3 className="text-lg font-medium">{item.cafe}</h3>
              <h3 className="text-lg font-medium" onClick={() => getItem(item)}><FavoriteIcon sx={{ stroke: "yellow", strokeWidth: 1 }} className="text-red-600 text-xl"/></h3>
            </div>
              
              <h3 className="text-sm font-medium text-white">{item.price}</h3>
            </div>
          </div>
        </div>
      ))}
    </div>
  );
};

export default ProductCard;

const ImageGrid = ({images, favourites}) => {

    // console.log(favourites)

    return (

        <div className='fixed bg-neutral-900 w-full'>
            <p className='m-2 text-white text-center'>Favourites</p>
            <div className="flex flex- justify-center ">
            {favourites && favourites.length>0 ? 
                favourites.map((item) => (
                    <div>
                        <img src={item.img} className="w-24 h-24 sm:w-32 sm:h-32 rounded-full m-2" alt="Image 1" />
                        <span className='text-white flex justify-center'>{item.cafe}</span>
                    </div>
                )) : <p>No favourites yet</p>}
            </div>
        </div>
    );
};
export default ImageGrid;

CodePudding user response:

getItem should spread the old favorites. Currently it will set the state to an array two values, the old favorites and the item

function getItem(item) {
  setFavourites([...favourites, item]);
}

CodePudding user response:

Possibly a copy paste issue in your example, but it looks like the route to UserProfile is unclosed syntax error.

Rather than:

<Route path='/profile' element={<UserProfile images={images} getItem={getItem}/>} favourites={favourites} />

it looks like it should be:

<Route path='/profile' element={<UserProfile images={images} getItem={getItem}/>} favourites={favourites} /> } />
  • Related