Как забрасывать данные из одной компоненты в другую

У меня есть 2 компонента: Product_details и Cart - моя корзина с элементами. Я пытаюсь забрасывать по кнопке Buy их в корзину и отрисовывать их, как в обычном магазине. Когда я нажимаю на кнопку Buy, у меня только вызывается ошибка в консоли Expected onClick listener to be a function, instead got a value of object type. , данные в компоненте cart НЕ рисуются, но приложение дальше работает. Как можно забрасывать эти данные в компоненту Cart?

Cart.js

import React from "react";
import {useSelector} from "react-redux";

export let Cart = () => {

let {id, title, description, image} = useSelector(
    (state) => state.products_reducer.cart_products_list)

return (<div>
    <div key={id}>
        <p>{title}</p>
    </div>
</div>)
}

Action_creators.js

import {
PRODUCTS_ARE_LOADED,
DIFFERENT_PRODUCT_ARE_LOADED,
ADD_TO_CART,
} from "./Action_types";

let products_are_loaded = (payload) => ({type: PRODUCTS_ARE_LOADED, payload})
let different_product_are_loaded = (payload) => ({type: DIFFERENT_PRODUCT_ARE_LOADED, payload})
let add_to_cart = (payload) => ({type: ADD_TO_CART, payload})

export {
products_are_loaded,
different_product_are_loaded,
add_to_cart
}

Reducers.js

import {
PRODUCTS_ARE_LOADED,
DIFFERENT_PRODUCT_ARE_LOADED,
ADD_TO_CART,
REMOVE_FROM_CART} from "./Action_types";

let initialState = {
all_products : [],
different_product : [],
cart_products_list : []
}

let products_reducer = (state = initialState, action) => {
switch (action.type) {
    case PRODUCTS_ARE_LOADED : {
        return {
            ...state,
            all_products: action.payload
        }
    }
    case DIFFERENT_PRODUCT_ARE_LOADED : {
        return {
            ...state,
            different_product: action.payload
        }
    }

    case ADD_TO_CART : {
        return {
            ...state,
            cart_products_list: [...state.cart_products_list, action.newItem]
        }
    }

    default:
        return state;
}
}
export default products_reducer;

Product_detail.js

import React, {useEffect} from "react";
import {useParams} from "react-router-dom";
import {useDispatch, useSelector} from "react-redux";
import {add_to_cart, different_product_are_loaded} from "../Redux/Action_creators";

export let Product_Detail = () => {

let {id} = useParams();
let dispatch = useDispatch();
let {title, description, image} = useSelector(
    (state) => state.products_reducer.different_product);

let fetchProductDifferent = async () => {
    try {
        let response = await fetch(`https://fakestoreapi.com/products/${id}`)
        let json = await response.json();
        dispatch(different_product_are_loaded(json));
    } catch (error) {
        console.log(error);
    }
}

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

return (<div className="product_detail_page">
    <div key={id} className="product_detail">
            <div>
                <h2>{title}</h2>
                <img src={image}/>
            </div>
            <div>
                <p>{description}</p>
            </div>
            <button onClick={dispatch(add_to_cart(id))}>Buy</button>
    </div>
        </div>)
}

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

Автор решения: Konstantin Modin

action.newItem не имеет никакого значения. В Reducers.js необходимо обновить данное место:

case ADD_TO_CART: {
      const newItem = state.all_products.find(
        (item) => item.id == action.payload
      );
      return {
        ...state,
        cart_products_list: [...state.cart_products_list, newItem],
      };
    }

Card.js:

import React from "react";
import { useSelector } from "react-redux";

export const Cart = () => {
  const cartProductsList = useSelector(
    (state) => state.products_reducer.cart_products_list
  );

  return (
    <div>
      {cartProductsList.map(({ id, title, description, image }) => (
        <div key={id}>
          <p>{title}</p>
          <p>{description}</p>
          <img src={image} alt={`product ${id}`} style={{ maxWidth: "100px" }}/>
        </div>
      ))}
    </div>
  );
};
→ Ссылка