Solucionado (ver solução)
Solucionado
(ver solução)
4
respostas

[Dúvida] Como reutilizar dados de um componente em outro

Alguém pode me orientar o que fazer ? Estou preso no meu código já faz um tempinho...

Meu objetivo é pegar os dados de cada item criado no setSelectedItem e usar na lista dentro do componente ShoppingCartComponent. Agradeço a quem pode me ajudar kk.

Componente ShoppingCartComponent

export const ShoppingCartComponent = ({ selectedItem, onClose }) => {
    const ref = useRef(null)

    const handleCloseClick = () => {
        closeAnimation(ref.current, 200, onClose)
    }

    useEffect(() => {
        animateElements(ref.current, 200, 0)

        const handleClickOutside = (event) => {
            if (ref.current && !ref.current.contains(event.target)) {
                handleCloseClick()
            }
        }

        document.addEventListener('mousedown', handleClickOutside)

        return () => {
            document.removeEventListener('mousedown', handleClickOutside)
        }
    }, [onClose])

    return (
        <>
            <ModalOverlay />

            <aside className='shopping-cart-menu' ref={ref}>
                <section>
                    <header>
                        <IoIosClose onClick={handleCloseClick} className='icon-close' />
                    </header>

                    <nav>
                        <ul>
                            {selectedItem && selectedItem ? (
                                <li key={selectedItem.id}>
                                    <img className="image" src={selectedItem.image} alt={`Imagem ${selectedItem.title}`} />
                                    <p>{selectedItem.title}</p>
                                    <p>{selectedItem.description}</p>
                                    <p>{selectedItem.price}</p>
                                </li>
                            ) : (
                                <li> Carrinho vazio </li>
                            )}
                        </ul>
                    </nav>
                </section>
            </aside>
        </>
    )
}

Componente CardMenu

export const CardMenu = ({ data }) => {
    const [selectedItem, setSelectedItem] = useState(null)
    const [showModal, setShowModal] = useState(false)

    const handleClickBuy = (item) => {
        setSelectedItem(item)
        console.log(item)
    }

    const handleClickMoreInformation = (item) => {
        setSelectedItem(item)
        setShowModal(true)
    }

    const clickCloseModal = () => {
        setShowModal(false)
    }

    return (
        <>
            <ul className="menu-list">
                {data && data.map((item) => {
                    return (
                        <li className="item" key={item.id}>
                            <div className='leftSide'>
                                <div className='topSide'>
                                    <img className="image" src={item.image} alt={`Imagem ${item.title}`}/>
                                    <h2 className="title"> {item.title} </h2>
                                </div>
                                <div className='bottomSide'>
                                    <p className="description"> {item.description} </p>

                                    <div className='value'>
                                        <Button size='s' onClick={() => handleClickBuy(item)}>
                                            <CiShoppingCart className='icon-button' />
                                        </Button>
                                        <p className="price"> {currencyFormat(item.price)} </p>
                                        <button className='more-information'>
                                            <p className='text-more-information' onClick={() => handleClickMoreInformation(item)}> Mais informações</p>
                                        </button>
                                    </div>
                                </div>
                            </div>
                            <div className="rightSide">
                                <img src={radiationIcon} alt='imagem ilustrativa de aviso nuclear' className='radiationImage'></img>
                                <img src={vaultBoy} alt='ilustração de um garoto de fallout (vault boy)' className='vaultBoyImage'></img>
                            </div>
                        </li>
                    )
                })}
            </ul>

            {showModal && <MenuModal item={selectedItem} onClose={ clickCloseModal } />}
        </>
    )
}
4 respostas

Oi, Caio, tudo bem?

Entendi que você quer reutilizar os dados do selectedItem do componente CardMenu no componente ShoppingCartComponent. Para fazer isso, você pode passar o selectedItem como uma prop para o ShoppingCartComponent e, assim, reutilizar esses dados.

import { ShoppingCartComponent } from './ShoppingCartComponent' 

export const CardMenu = ({ data }) => {
    const [selectedItem, setSelectedItem] = useState(null)
    const [showModal, setShowModal] = useState(false)

    const handleClickBuy = (item) => {
        setSelectedItem(item)
        console.log(item)
    }

    const handleClickMoreInformation = (item) => {
        setSelectedItem(item)
        setShowModal(true)
    }

    const clickCloseModal = () => {
        setShowModal(false)
    }

    return (
        <>
            <ul className="menu-list">
                {data && data.map((item) => {
                    return (
                        <li className="item" key={item.id}>
                            <div className='leftSide'>
                                <div className='topSide'>
                                    <img className="image" src={item.image} alt={`Imagem ${item.title}`}/>
                                    <h2 className="title"> {item.title} </h2>
                                </div>
                                <div className='bottomSide'>
                                    <p className="description"> {item.description} </p>

                                    <div className='value'>
                                        <Button size='s' onClick={() => handleClickBuy(item)}>
                                            <CiShoppingCart className='icon-button' />
                                        </Button>
                                        <p className="price"> {currencyFormat(item.price)} </p>
                                        <button className='more-information'>
                                            <p className='text-more-information' onClick={() => handleClickMoreInformation(item)}> Mais informações</p>
                                        </button>
                                    </div>
                                </div>
                            </div>
                            <div className="rightSide">
                                <img src={radiationIcon} alt='imagem ilustrativa de aviso nuclear' className='radiationImage'></img>
                                <img src={vaultBoy} alt='ilustração de um garoto de fallout (vault boy)' className='vaultBoyImage'></img>
                            </div>
                        </li>
                    )
                })}
            </ul>

            {showModal && <MenuModal item={selectedItem} onClose={ clickCloseModal } />}
            <ShoppingCartComponent selectedItem={selectedItem} onClose={() => setShowModal(false)} />
        </>
    )
}

O seu ShoppingCartComponent já está preparado para receber a prop selectedItem, então não é necessário fazer nenhuma modificação adicional nele. Com essas mudanças, o selectedItem será passado do CardMenu para o ShoppingCartComponent, permitindo que você reutilize os dados conforme necessário.

Todavia, vale ressaltar que como não tenho acesso ao cenário completo do projeto outros testes terão de ser feitos a fim de obter o resultado esperado, mas espero que esta resposta seja um bom ponto de partida para a resolução do seu problema.

Espero que dê tudo certo. Abraços!

Caso este post tenha lhe ajudado, por favor, marcar como solucionado ✓. Bons Estudos!

Só que tem um porem, o meu ShoppingCartComponent já está sendo usado no meu componente Header, meu objetivo é passar os dados de cada item clicado para dentro do ShoppingCartComponent que já está sendo usado no meu header.

Como poder ver a seguir

import './Header.css'
import { CiShoppingCart } from "react-icons/ci"
import { FaCircle } from "react-icons/fa"
import { HiOutlineMenuAlt2 } from "react-icons/hi"
import { useEffect, useState } from 'react'
import pageLogo from '../../assets/PageIcon.svg'
import { MenuBurguer } from './MenuBurguer/MenuBurguerComponent'
import { ShoppingCartComponent } from './ShoppingCart/ShoppingCartComponent'

export const HeaderComponent = () => {
    const [size, setSize] = useState(false)
    const [showMenu, setShowMenu] = useState(false)
    const [showShoppingCart, setShowShoppingCart] = useState(false)
    const [cartItem, setCartItem] = useState([])

    const clickOpenShoppingCart = () => {
        setShowShoppingCart(true)
    }

    const clickCloseShoppingCart = () => {
        setShowShoppingCart(false)
    }

    const clickOpenMenu = () => {
        setShowMenu(true)
    }

    const clickCloseMenu = () => {
        setShowMenu(false)
    }

    useEffect(() => {
        const handleScroll = () => {
            const scrollPosition = window.pageYOffset
            const sizeWindow = window.innerWidth
    
            if (sizeWindow < 1280 && scrollPosition > 40) {
                setSize(true)
            } else {
                setSize(false)
            }
        }

        window.addEventListener('scroll', handleScroll)

        return () => {
            window.removeEventListener('scroll', handleScroll)
        }
    }, [])

    const handleAddToCart = (item) => {
        setCartItem((prevItem) => [...prevItem, item])
    }

    return (
        <>
            {showMenu && <MenuBurguer onclose={clickCloseMenu}/>}
            {showShoppingCart &&  <ShoppingCartComponent onClose={ clickCloseShoppingCart } />}

            <div id='header-content' className='header-content' style={{ backgroundColor: size ? 'rgb(0,0,0,70%)' : 'transparent'}} >
                
                <div className='btn-menu'> 
                <HiOutlineMenuAlt2 className='icon-menu' onClick={clickOpenMenu}/> 
                </div>

                <img src={pageLogo} alt='Logotipo hamburgueria'></img>

                <nav>
                    <ul>
                        <li><a href=''> MAIS PEDIDOS </a></li>
                        <li><a href=''> CARNE </a></li>
                        <li><a href=''> FRANGO </a></li>
                        <li><a href=''> ACOMPANHAMENTOS </a></li>
                    </ul>
                </nav>

                <div className='btns'>
                    <button className='btn-shoppingCart' onClick={ clickOpenShoppingCart }> 
                        <FaCircle className='icon-circle' />
                        <CiShoppingCart className='icon-shoppingCart' /> 
                    </button>
                </div>
            </div>
        </>
    )
}

{/* */}

Oi, Caio, tudo bem?

Como se trata de um projeto pessoal e eu não tenho acesso ao cenário completo, posso te fornecer um norte sobre como proceder. Para passar os dados de cada item clicado para o ShoppingCartComponent que já está sendo usado no seu HeaderComponent, você pode usar um estado global ou um contexto de React, para mais informações você pode consultar a documentação. As informações estão em inglês, mas você pode traduzir clicando com o botão direito do mouse em "Traduzir para o português".

Além disso, caso queira, temos o curso de React: gerencie estados globalmente com Context API, especificamente na aula 2 Explorando a context API o instrutor vai explorar melhor como compartilhar e consumir contexto.

Espero que dê tudo certo. Abraços!

Caso este post tenha lhe ajudado, por favor, marcar como solucionado ✓. Bons Estudos!
solução!

Minha solução foi passando em props até o componente pai e assim usar