通过 useContext 传递函数
Passing function through useContext
我目前正在为 React 上下文而苦苦挣扎。我想传递允许在上下文中显示/隐藏购物车逻辑的函数,而不是在组件之间使用道具。
我不明白为什么在单击 HeaderCartButton 组件中的按钮时,它不会触发我上下文中的 **onClick={ctx.onShowCart}**,即使当我控制台记录 cartCtx.state它已正确更新,然后应将组件添加到 App.js
//App.js
import { useContext } from "react";
import Header from "./components/Layout/Header";
import Meals from "./components/Meals/Meals";
import Cart from "./components/Cart/Cart";
import CartProvider from "./store/CartProvider";
import CartContext from "./store/cart-context";
function App() {
const ctx = useContext(CartContext);
return (
<CartProvider>
{ctx.state && <Cart />}
<Header />
<main>
<Meals />
</main>
</CartProvider>
);
}
export default App;
//cart-context.js
import React from "react";
const CartContext = React.createContext({
state: false,
onShowCart: () => {},
onHideCart: () => {},
items: [],
totalAmount: 0,
addItem: (item) => {},
removeItem: (id) => {},
});
export default CartContext;
//CartProvider.js
import CartContext from "./cart-context";
import { useState } from "react";
const CartProvider = (props) => {
const [cartIsShown, setCartIsShown] = useState(false);
const showCartHandler = () => {
setCartIsShown(true);
};
const hideCartHandler = () => {
setCartIsShown(false);
};
const handleAddItem = (item) => {};
const handleRemoveItem = (id) => {};
const cartCtx = {
state: cartIsShown,
onShowCart: showCartHandler,
onHideCart: hideCartHandler,
items: [],
totalAmount: 0,
addItem: handleAddItem,
removeItem: handleRemoveItem,
};
return (
<CartContext.Provider value={cartCtx}>
{props.children}
</CartContext.Provider>
);
};
export default CartProvider;
//Header.js
import { Fragment } from "react";
import HeaderCartButton from "./HeaderCartButton";
import mealsImage from "../../assets/meals.jpg";
import classes from "./Header.module.css";
const Header = (props) => {
return (
<Fragment>
<header className={classes.header}>
<h1>ReactMeals</h1>
<HeaderCartButton />
</header>
<div className={classes["main-image"]}>
<img src={mealsImage} alt="A table full of delicious food!" />
</div>
</Fragment>
);
};
export default Header;
//HeaderCartButton.js
import CartIcon from "../Cart/CartIcon";
import { useContext } from "react";
import classes from "./HeaderCartButton.module.css";
import CartContext from "../../store/cart-context";
const HeaderCartButton = (props) => {
const ctx = useContext(CartContext);
const numberOfCartItems = ctx.items.reduce((accumulator, item) => {
return accumulator + item.amount;
}, 0);
return (
<button className={classes.button} onClick={ctx.onShowCart}>
<span className={classes.icon}>
<CartIcon />
</span>
<span>Your Cart</span>
<span className={classes.badge}>{numberOfCartItems}</span>
</button>
);
};
export default HeaderCartButton;
感谢您的帮助
如果您查看您的 App 组件,您正在 提供商之外使用 CartContext。
function App() {
const ctx = useContext(CartContext);
return (
<CartProvider>
{ctx.state && <Cart />}
<Header />
<main>
<Meals />
</main>
</CartProvider>
);
}
您应该对其进行修改,使其类似于以下内容,其中您使用的是供应商内部的上下文。
const Main = () => {
return <CartProvider><App /></CartProvider>
}
function App() {
const ctx = useContext(CartContext);
return (
<>
{ctx.state && <Cart />}
<Header />
<main>
<Meals />
</main>
</>
);
}
我目前正在为 React 上下文而苦苦挣扎。我想传递允许在上下文中显示/隐藏购物车逻辑的函数,而不是在组件之间使用道具。 我不明白为什么在单击 HeaderCartButton 组件中的按钮时,它不会触发我上下文中的 **onClick={ctx.onShowCart}**,即使当我控制台记录 cartCtx.state它已正确更新,然后应将组件添加到 App.js
//App.js
import { useContext } from "react";
import Header from "./components/Layout/Header";
import Meals from "./components/Meals/Meals";
import Cart from "./components/Cart/Cart";
import CartProvider from "./store/CartProvider";
import CartContext from "./store/cart-context";
function App() {
const ctx = useContext(CartContext);
return (
<CartProvider>
{ctx.state && <Cart />}
<Header />
<main>
<Meals />
</main>
</CartProvider>
);
}
export default App;
//cart-context.js
import React from "react";
const CartContext = React.createContext({
state: false,
onShowCart: () => {},
onHideCart: () => {},
items: [],
totalAmount: 0,
addItem: (item) => {},
removeItem: (id) => {},
});
export default CartContext;
//CartProvider.js
import CartContext from "./cart-context";
import { useState } from "react";
const CartProvider = (props) => {
const [cartIsShown, setCartIsShown] = useState(false);
const showCartHandler = () => {
setCartIsShown(true);
};
const hideCartHandler = () => {
setCartIsShown(false);
};
const handleAddItem = (item) => {};
const handleRemoveItem = (id) => {};
const cartCtx = {
state: cartIsShown,
onShowCart: showCartHandler,
onHideCart: hideCartHandler,
items: [],
totalAmount: 0,
addItem: handleAddItem,
removeItem: handleRemoveItem,
};
return (
<CartContext.Provider value={cartCtx}>
{props.children}
</CartContext.Provider>
);
};
export default CartProvider;
//Header.js
import { Fragment } from "react";
import HeaderCartButton from "./HeaderCartButton";
import mealsImage from "../../assets/meals.jpg";
import classes from "./Header.module.css";
const Header = (props) => {
return (
<Fragment>
<header className={classes.header}>
<h1>ReactMeals</h1>
<HeaderCartButton />
</header>
<div className={classes["main-image"]}>
<img src={mealsImage} alt="A table full of delicious food!" />
</div>
</Fragment>
);
};
export default Header;
//HeaderCartButton.js
import CartIcon from "../Cart/CartIcon";
import { useContext } from "react";
import classes from "./HeaderCartButton.module.css";
import CartContext from "../../store/cart-context";
const HeaderCartButton = (props) => {
const ctx = useContext(CartContext);
const numberOfCartItems = ctx.items.reduce((accumulator, item) => {
return accumulator + item.amount;
}, 0);
return (
<button className={classes.button} onClick={ctx.onShowCart}>
<span className={classes.icon}>
<CartIcon />
</span>
<span>Your Cart</span>
<span className={classes.badge}>{numberOfCartItems}</span>
</button>
);
};
export default HeaderCartButton;
感谢您的帮助
如果您查看您的 App 组件,您正在 提供商之外使用 CartContext。
function App() {
const ctx = useContext(CartContext);
return (
<CartProvider>
{ctx.state && <Cart />}
<Header />
<main>
<Meals />
</main>
</CartProvider>
);
}
您应该对其进行修改,使其类似于以下内容,其中您使用的是供应商内部的上下文。
const Main = () => {
return <CartProvider><App /></CartProvider>
}
function App() {
const ctx = useContext(CartContext);
return (
<>
{ctx.state && <Cart />}
<Header />
<main>
<Meals />
</main>
</>
);
}