Как повесить функцию на onClick в дочернем компоненте и вывести её в родительском?

Как повесить функцию на onClick в дочернем компоненте и вывести её в родительском через промежуточный компонент? Помогите, пожалуйста.

Родительский компонент (в котором есть функция addToCart).

import React, {useEffect, useState} from 'react';
import {API_KEY, API_URL} from './config'
import {Preloader} from './Preloader'
import {GoodsList} from './GoodsList';
import Pagination from './Pagination';
import {Cart} from './Cart'


const Shop = () => {
    const [goods, setGoods] = useState([]);
    const [loading, setLoading] = useState(true);
    const [currentPage, setCurrentPage] = useState(1);
    const [countriesPerPage] = useState(12);
    const [order, setOrder] = useState([]);

    useEffect(function getGoods() {
        fetch(API_URL, { 
            headers: {
                Authorization: API_KEY
            }}).then((response)=> response.json())
            .then((data) => {
                data.shop && setGoods(data.shop);
                setLoading(false)
                

            })
    }, []) 

    const lastCountryIndex = currentPage * countriesPerPage ;
    const firstCountyIndex = lastCountryIndex - countriesPerPage;
    const currentCountry = goods.slice(firstCountyIndex, lastCountryIndex)

    const paginate = pageNumber => setCurrentPage(pageNumber)
    const nextPage = () => {
        const lastPage = Math.ceil(goods.length / countriesPerPage);
        if (currentPage !== lastPage) {
            setCurrentPage(currentPage + 1);
        }
    };
    const lastPage = () => {
        if (currentPage !== 1) {
            setCurrentPage(currentPage - 1);
        }
    };
    
    const addToCart = (item) => {
        console.log('test')
    }

         return (
            <main className="container content">
                <Cart quantity={order.length} />
                {
                    loading ? <Preloader /> : <GoodsList goods={currentCountry} addToCart={addToCart}/>
                }
                <Pagination 
                countriesPerPage={countriesPerPage} 
                totalCountries = {goods.length}
                paginate={paginate}/>

                <button className="btn-primary" onClick={lastPage}> Prev </button>
                <button className="btn-primary" onClick={nextPage}> Next </button>
                </main>
            ) 

}
export { Shop }

Промежуточный компонент (List).

import { GoodsItem } from "./GoodsItem";

function GoodsList(props) {
    const {goods = []} = props;
    return <div className="goods">
        {goods.map(item => (
            <GoodsItem key={item.id} {...item} addToCart={props.addToCart}/>
        ))}
</div>}

export {GoodsList};

Дочерний компонент (в котором нужно повесить функцию addToCart на onClick и передать её в родительский).

function GoodsItem(props, addToCart) {
    const {
        mainId,
        displayName, 
        displayDescription,
        displayType,
        displayAssets: [ {
          background
        }],
        price: {
          finalPrice
        }
    } = props;
    
    return (
        
  <div className="row">
    <div className="col s12 m6">
      <div className="card" id={mainId}>
        <div className="card-image">
          <img src={background} alt={displayName} />
          <span className="card-title">{displayName}</span>
          <br />
          <span>{displayType}</span>
          <br />
        </div>
        <div className="card-content">
          <p>{displayDescription}</p>
          <p class="price">{finalPrice} руб</p>
          <a onClick = {addToCart} className="btn-floating halfway-fab waves-effect waves-light red"><i className="material-icons">add</i></a> 
        </div>
      </div>
    </div>
  </div>
            
    )
}


export {GoodsItem};


Ответы (1 шт):

Автор решения: Probe_

Если тебе нужно добавлять по кнопке товар в корзину, тогда можешь просто передавать функцию setGoods. Потом уже внутри компонента можно будет по онклику вызывать ее вместе с функцией отправки добавления товара в корзину.

Вообще, у тебя по идее идет связь с бэком. Ты можешь просто внутри компонента GoodsItem описать функцию, которая будет отправлять запрос на бэк. Если все хорошо, то нужно запросить у сервера новый список товаров в корзине или просто изменить через setGoods

→ Ссылка