[英]React, pass function as prop in different component
I have a simple list of products and a cart that I would like to add the products to.我有一个简单的产品列表和一个我想将产品添加到其中的购物车。
The Products
and Cart
are separate components in the index file. Products
和Cart
是索引文件中的独立组件。
I have the function to add the products to the cart in the Products components but how do I pass this to the Cart component that is outside the Products component.我有 function 将产品添加到 Products 组件中的购物车,但是如何将其传递给 Products 组件之外的 Cart 组件。
import React, { useState } from "react";
import { render } from "react-dom";
import Cart from "./Cart";
import Products from "./Products";
import "./style.css";
const App = () => {
return (
<div>
<Products />
<Cart />
</div>
);
};
render(<App />, document.getElementById("root"));
https://stackblitz.com/edit/react-ts-txpsds https://stackblitz.com/edit/react-ts-txpsds
// index.tsx import React from "react"; import { render } from "react-dom"; import Cart from "./Cart"; import { CartProvider } from "./context"; import Products from "./Products"; import "./style.css"; const App = () => { return ( <CartProvider> <div> <Products /> <Cart /> </div> </CartProvider> ); }; render(<App />, document.getElementById("root"));
// Products.tsx import React, { createContext, useCallback, useContext, useState } from "react"; import { AddCartContext } from "./context"; import { IProduct } from "./interface"; const Products = () => { const addItems = useContext(AddCartContext); const items = [ { id: 1, name: "Product One", price: 20 }, { id: 2, name: "Product Two", price: 56 }, { id: 3, name: "Product Three", price: 13 } ]; const handleClick = ( e: React.MouseEvent<HTMLInputElement, MouseEvent>, item: IProduct ) => { e.preventDefault(); addItems(item); }; const listItems = items.map(item => ( <div key={item.id}> {`${item.name}: £${item.price}`} <input type="submit" value="+" onClick={e => handleClick(e, item)} /> </div> )); return ( <div> <div> <h2>Products</h2> {listItems} </div> </div> ); }; export default Products;
const Cart = () => { const items = useContext(CartContext); const cartItems = items.map((item, index) => ( <div key={index}>{`${item.name}: £${item.price}`}</div> )); return ( <div> <h2>Cart</h2> {cartItems} </div> ); };
// context.tsx import React, { createContext, useCallback, useRef, useState } from "react"; export const CartContext = createContext([]); export const AddCartContext = createContext(item => {}); export function CartProvider(props) { const [items, setItems] = useState([]); const itemsRef = useRef(items); itemsRef.current = items; return ( <AddCartContext.Provider value={useCallback(item => { setItems([...itemsRef.current, item]); }, [])} > <CartContext.Provider value={items}> {props.children} </CartContext.Provider> </AddCartContext.Provider> ); }
If you want to share a property
or function
between multiple components
you need to put that property
or function
in closest parent
of those components
so you can pass them as props
.如果您想在多个
components
之间共享一个property
或function
您需要将该property
或function
放在这些components
的最近parent
级中,以便您可以将它们作为props
传递。
In your case try to add your function
to your App
Component and then pass the function to both Products
and Cart
Components在您的情况下,尝试将您的
function
添加到您的App
组件,然后将 function 传递给Products
和Cart
组件
There are 2 work-arounds for your problem.您的问题有两种解决方法。
You can make the Cart
component as the child component of Products through which you can pass the addToCart()
as Props to Cart.您可以将
Cart
组件作为 Products 的子组件,通过它您可以将addToCart()
作为 Props 传递给 Cart。 [but it is not meaningful] [但没有意义]
You can bring the state
from Product Component to App
ie make the App
as a stateful component and for products and Cart
, make them as statelesss.您可以将
state
从 Product Component 带到App
,即将App
作为有状态组件,而对于products and Cart
,将它们设为无状态。 Pass the data and methods as props.将数据和方法作为道具传递。
Take a look at the react docs for Lifting state up .看一下Lifting state up的反应文档。
Move your cart
state up into the closest common ancestor - App
.将您的
cart
state 向上移动到最近的共同祖先App
中。
From App
, pass cart
and setCart
as props into both Products
and Cart
as needed.从
App
中,根据需要将cart
和setCart
作为道具传递给Products
和Cart
。
import React, { useState, Dispatch, SetStateAction } from "react";
import { render } from "react-dom";
interface IProduct {
id: number;
name: string;
price: number;
}
const App = () => {
const [cart, setCart] = useState<IProduct[]>([]);
return (
<div>
<Products cart={cart} setCart={setCart} />
<Cart cart={cart} />
</div>
);
};
function Cart({ cart = [] }: { cart: IProduct[] }) {
return (
<div>
<h2>Cart</h2>
{cart.map(item => (
<div>{`${item.name}: £${item.price}`}</div>
))}
</div>
);
}
function Products({
cart,
setCart
}: {
cart: IProduct[];
setCart: Dispatch<SetStateAction<IProduct[]>>;
}) {
const items: IProduct[] = [{id: 1,name: "Product One",price: 20},{id: 2,name: "Product Two",price: 56},{id: 3,name: "Product Three",price: 13}];
const handleClick = (
e: React.MouseEvent<HTMLInputElement, MouseEvent>,
item: IProduct
) => {
e.preventDefault();
setCart([...cart, item]);
};
return (
<div>
<div>
<h2>Products</h2>
{items.map(item => (
<div>
{`${item.name}: £${item.price}`}
<input
type="submit"
value="+"
onClick={e => setCart([...cart, item])}
/>
</div>
))}
</div>
</div>
);
}
render(<App />, document.getElementById("root"));
Keep a common items variable and a function addItems in App.tsx and you need to pass this function as prop to Product component which when adds a product will call this same function in App.tsx file and update the items list.And this items list can be passed to the Cart component. Keep a common items variable and a function addItems in App.tsx and you need to pass this function as prop to Product component which when adds a product will call this same function in App.tsx file and update the items list.And this items list可以传递给 Cart 组件。 Here check this live demo: https://stackblitz.com/edit/react-ts-qq5cea?file=index.tsx
在这里查看这个现场演示: https://stackblitz.com/edit/react-ts-qq5cea?file=index.tsx
I improved your code a little, the main thing that needed to be done was to move the state to a higher level我稍微改进了你的代码,需要做的主要事情是将 state 移动到更高的级别
https://stackblitz.com/edit/react-ts-iicy7v?file=Shop.tsx https://stackblitz.com/edit/react-ts-iicy7v?file=Shop.tsx
const App = () => {
return (
<div>
<Shop Products={Products} Cart={Cart} />
</div>
);
};
move logic to Shop:将逻辑移动到商店:
const Shop = ({ Products, Cart }) => {
const [cart, setCart] = useState([]);
const addToCart = (item: IProduct) => {
setCart([...cart, item]);
};
const removeFromCart = (item: IProduct) => {
const itemWillBeRemoved = cart.find(e => e.id === item.id);
const index = cart.indexOf(itemWillBeRemoved);
const newCart = [...cart];
newCart.splice(index, 1);
setCart(newCart);
};
const items = [
{
id: 1,
name: "Product One",
price: 20
},
{
id: 2,
name: "Product Two",
price: 56
},
{
id: 3,
name: "Product Three",
price: 13
}
];
return (
<div>
<Products items={items} addToCart={addToCart} />
<Cart items={cart} removeFromCart={removeFromCart} />
</div>
);
};
But the best way - use State Management但最好的办法——使用 State 管理
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.