【问题标题】:React Context Api using function from context provider使用来自上下文提供者的函数反应 Context Api
【发布时间】:2021-10-03 18:23:06
【问题描述】:

我正在尝试使用 contextApi 来处理购物车中的商品列表。

我已经有一个项目中的身份验证上下文并且它工作正常,但是这个新的购物车上下文给我带来了问题。

我有一个名为 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;

【问题讨论】:

  • 在 javascript 中,箭头函数和“常规”函数声明具有不同的作用域(blog.kevinchisholm.com/javascript/context-object-literals),我会首先尝试将所有函数更改为箭头函数(例如:更改异步函数句柄购买(.. .) 到 const handleBuy = async () => {}) 看看是否能解决问题

标签: reactjs frontend react-context


【解决方案1】:

此错误通常发生是因为BuyButton 不是ShoppingCartProvider 的子对象,并且您在初始化上下文时没有为addItem 方法提供默认值。

您可以通过为ShoppingCartContext 指定addItem 的默认值来支持这一点,如下所示:

const ShoppingCartContext = createContext<ShoppingCartContextType>({
    addItem: () => alert('test')
});

以这个 CodeSandbox 为例:

https://codesandbox.io/s/nifty-williams-ziysn?file=/src/App.tsx

【讨论】:

  • 这正是发生的事情,谢谢,我可以像你说的那样添加一个默认值,或者将所有内容包装在 de ShoppigCartProvider 中
猜你喜欢
  • 2021-08-24
  • 2021-07-04
  • 1970-01-01
  • 2020-08-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多