React Context Api 使用来自上下文提供者的函数
React Context Api using function from context provider
我正在尝试使用 contextApi 来处理商品的购物车列表。
我已经在项目中有一个 auth 上下文并且它工作正常,但是这个新的 cart 上下文给我带来了问题。
我有一个名为 addItem(item: ShoppingItem) 的函数,当我尝试在我的组件上使用此函数时,我收到一条错误消息,指出 addItem 不是一个函数。我将在下面显示我的代码。谢谢
购物车上下文:
import { createContext, useState } from 'react';
export interface ShoppingCartContextType {
list: number;
addItem(item: ShoppingItem): Promise<void>;
logout(): void;
};
export interface ShoppingItem {
id: string
}
const ShoppingCartContext = createContext<ShoppingCartContextType>({} as ShoppingCartContextType);
export const ShoppingCartProvider: React.FC = ({children}) => {
const [shoppingCart, setShoppingCart] = useState<ShoppingItem[]>([{id: "item de merda"}]);
async function addItem(item: ShoppingItem): Promise<void>{
console.log('adding an item')
setShoppingCart(current => [...current, item])
return new Promise((resolve) => {
resolve();
});
}
function logout() {
localStorage.clear();
}
return (
<ShoppingCartContext.Provider
value= {{ list: shoppingCart.length, addItem, logout}}>
{children}
</ShoppingCartContext.Provider>
);
};
export default ShoppingCartContext;
使用上下文的组件:
import { useContext } from 'react';
import './styles.css';
import { toast } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';
import { FaShoppingCart } from 'react-icons/fa';
import AuthContext from '../../contexts/auth';
import ShoppingCartContext, { ShoppingItem } from '../../contexts/shoppingCart';
import { NonAuthRoutes } from '../../helpers/Authentication/authenticationRoutes';
import { useHistory } from 'react-router-dom';
interface Props {
productId: string | undefined;
productName: string | undefined;
price: number | undefined;
quantity: number | undefined;
}
function BuyButton({productId, productName, price, quantity}: Props) {
const history = useHistory();
const {signed} = useContext(AuthContext);
const {addItem} = useContext(ShoppingCartContext);
async function handleBuy(e: React.FormEvent<HTMLButtonElement>) {
e.stopPropagation();
addItem({id: productId} as ShoppingItem);
if (!signed) {
toast.warn("Você esta sendo redirecionado para a página de login", {autoClose:15000});
setTimeout(() => {
history.push(NonAuthRoutes.login);
}, 800);
return ;
}
}
return (
<div className="button-container">
<button className="button" onClick={handleBuy}>
<FaShoppingCart />
COMPRAR
</button>
</div>
);
}
export default BuyButton;
此错误通常是因为 BuyButton
不是 ShoppingCartProvider
的子项,并且您在初始化上下文时没有为 addItem
方法提供默认值。
您可以通过为 ShoppingCartContext
提供 addItem
的默认值来支持这一点,如下所示:
const ShoppingCartContext = createContext<ShoppingCartContextType>({
addItem: () => alert('test')
});
以这个 CodeSandbox 为例:
https://codesandbox.io/s/nifty-williams-ziysn?file=/src/App.tsx
我正在尝试使用 contextApi 来处理商品的购物车列表。
我已经在项目中有一个 auth 上下文并且它工作正常,但是这个新的 cart 上下文给我带来了问题。
我有一个名为 addItem(item: ShoppingItem) 的函数,当我尝试在我的组件上使用此函数时,我收到一条错误消息,指出 addItem 不是一个函数。我将在下面显示我的代码。谢谢
购物车上下文:
import { createContext, useState } from 'react';
export interface ShoppingCartContextType {
list: number;
addItem(item: ShoppingItem): Promise<void>;
logout(): void;
};
export interface ShoppingItem {
id: string
}
const ShoppingCartContext = createContext<ShoppingCartContextType>({} as ShoppingCartContextType);
export const ShoppingCartProvider: React.FC = ({children}) => {
const [shoppingCart, setShoppingCart] = useState<ShoppingItem[]>([{id: "item de merda"}]);
async function addItem(item: ShoppingItem): Promise<void>{
console.log('adding an item')
setShoppingCart(current => [...current, item])
return new Promise((resolve) => {
resolve();
});
}
function logout() {
localStorage.clear();
}
return (
<ShoppingCartContext.Provider
value= {{ list: shoppingCart.length, addItem, logout}}>
{children}
</ShoppingCartContext.Provider>
);
};
export default ShoppingCartContext;
使用上下文的组件:
import { useContext } from 'react';
import './styles.css';
import { toast } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';
import { FaShoppingCart } from 'react-icons/fa';
import AuthContext from '../../contexts/auth';
import ShoppingCartContext, { ShoppingItem } from '../../contexts/shoppingCart';
import { NonAuthRoutes } from '../../helpers/Authentication/authenticationRoutes';
import { useHistory } from 'react-router-dom';
interface Props {
productId: string | undefined;
productName: string | undefined;
price: number | undefined;
quantity: number | undefined;
}
function BuyButton({productId, productName, price, quantity}: Props) {
const history = useHistory();
const {signed} = useContext(AuthContext);
const {addItem} = useContext(ShoppingCartContext);
async function handleBuy(e: React.FormEvent<HTMLButtonElement>) {
e.stopPropagation();
addItem({id: productId} as ShoppingItem);
if (!signed) {
toast.warn("Você esta sendo redirecionado para a página de login", {autoClose:15000});
setTimeout(() => {
history.push(NonAuthRoutes.login);
}, 800);
return ;
}
}
return (
<div className="button-container">
<button className="button" onClick={handleBuy}>
<FaShoppingCart />
COMPRAR
</button>
</div>
);
}
export default BuyButton;
此错误通常是因为 BuyButton
不是 ShoppingCartProvider
的子项,并且您在初始化上下文时没有为 addItem
方法提供默认值。
您可以通过为 ShoppingCartContext
提供 addItem
的默认值来支持这一点,如下所示:
const ShoppingCartContext = createContext<ShoppingCartContextType>({
addItem: () => alert('test')
});
以这个 CodeSandbox 为例:
https://codesandbox.io/s/nifty-williams-ziysn?file=/src/App.tsx