Как забрасывать данные из одной компоненты в другую
У меня есть 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>
);
};