gpt4 book ai didi

reactjs - 如何以 useContext 作为依赖项正确使用 useEffect

转载 作者:行者123 更新时间:2023-12-03 08:16:15 31 4
gpt4 key购买 nike

我正在开发我的第一个 React 项目,但遇到以下问题。我希望我的代码如何工作:

  • 我将项目添加到可通过上下文访问的数组中 (context.items)
  • 我想在组件中运行 useEffect 函数,只要值发生变化,就会显示 context.items

我尝试过的:

  1. 将上下文( contextcontext.items )列为 useEffect 中的依赖项
  • 这导致组件在值更改时不更新
  • 列出context.items.length
    • 这会导致组件在数组长度发生变化时更新,而不是在单个项目的值发生变化时更新。
  • 将上下文包装在 Object.values(context)
    • 结果正是我想要的,除了 React 现在提示 *传递给 useEffect 的最后一个参数改变了渲染之间的大小。该数组的顺序和大小必须保持不变。 *

    您知道有什么方法可以修复此 React 警告或在上下文值更改时运行 useEffect 的不同方法吗?

    好吧,不想添加代码,希望这对我来说是一些简单的错误,但即使有一些答案,我仍然无法解决这个问题,所以在这里,减少了希望简化。

    上下文组件:

    const NewOrder = createContext({
    orderItems: [{
    itemId: "",
    name: "",
    amount: 0,
    more:[""]
    }],
    addOrderItem: (newOItem: OrderItem) => {},
    removeOrderItem: (oItemId: string) => {},
    removeAllOrderItems: () => {},
    });

    export const NewOrderProvider: React.FC = (props) => {
    // state
    const [orderList, setOrderList] = useState<OrderItem[]>([]);

    const context = {
    orderItems: orderList,
    addOrderItem: addOItemHandler,
    removeOrderItem: removeOItemHandler,
    removeAllOrderItems: removeAllOItemsHandler,
    };

    // handlers
    function addOItemHandler(newOItem: OrderItem) {
    setOrderList((prevOrderList: OrderItem[]) => {
    prevOrderList.unshift(newOItem);
    return prevOrderList;
    });
    }
    function removeOItemHandler(oItemId: string) {
    setOrderList((prevOrderList: OrderItem[]) => {
    const itemToDeleteIndex = prevOrderList.findIndex((item: OrderItem) => item.itemId === oItemId);
    console.log(itemToDeleteIndex);
    prevOrderList.splice(itemToDeleteIndex, 1);
    return prevOrderList;
    });
    }
    function removeAllOItemsHandler() {
    setOrderList([]);
    }

    return <NewOrder.Provider value={context}>{props.children}</NewOrder.Provider>;
    };

    export default NewOrder;

    显示数据的组件(实际上是一个模式):

    const OrderMenu: React.FC<{ isOpen: boolean; hideModal: Function }> = (
    props
    ) => {
    const NewOrderContext = useContext(NewOrder);
    useEffect(() => {
    if (NewOrderContext.orderItems.length > 0) {
    const oItems: JSX.Element[] = [];
    NewOrderContext.orderItems.forEach((item) => {
    const fullItem = {
    itemId:item.itemId,
    name: item.name,
    amount: item.amount,
    more: item.more,
    };
    oItems.push(
    <OItem item={fullItem} editItem={() => editItem(item.itemId)} key={item.itemId} />
    );
    });
    setContent(<div>{oItems}</div>);
    } else {
    exit();
    }
    }, [NewOrderContext.orderItems.length, props.isOpen]);

    对代码的一些注释:

    • 它实际上是用 Type Script 完成的,涉及一些额外的语法-content(和设置内容)是一种状态,它是返回值的一部分,因此可以动态设置某些部分-exit 是关闭模式的函数,也是包含 props.is Open 的原因
    • 有了这个.length 扩展当我从列表中删除一个项目时,模式会显示更改,但是,当我修改它时,不会更改 orderItems 的长度,而只会更改其中一个对象的值。
    • 正如我之前提到的,我找到了一些答案,他们说我应该像这样设置依赖项:...Object.values(<contextVariable>)这在技术上是可行的,但会导致 react 提示*传递给 useEffect 的最后一个参数改变了渲染之间的大小。该数组的顺序和大小必须保持不变。 *
    • 当我关闭并重新打开模式时,显示的值更改为正确的值,更改 props.isOpen说明问题出在上下文依赖上

    最佳答案

    您可以首先创建应用程序上下文,如下所示,我将使用购物车的示例

    import * as React from "react"

    const AppContext = React.createContext({
    cart:[]
    });

    const AppContextProvider = (props) => {
    const [cart,setCart] = React.useState([])

    const addCartItem = (newItem)=>{
    let updatedCart = [...cart];
    updatedCart.push(newItem)
    setCart(updatedCart)

    }

    return <AppContext.Provider value={{
    cart
    }}>{props.children}</AppContext.Provider>;
    };

    const useAppContext = () => React.useContext(AppContext);

    export { AppContextProvider, useAppContext };

    然后,您可以在应用程序中的任何位置使用应用程序上下文,如下所示,每当购物车的长度发生变化时,您都会在购物车中收到通知

    import * as React from "react";
    import { useAppContext } from "../../context/app,context";

    const ShoppingCart: React.FC = () => {
    const appContext = useAppContext();

    React.useEffect(() => {
    console.log(appContext.cart.length);
    }, [appContext.cart]);
    return <div>{appContext.cart.length}</div>;
    };

    export default ShoppingCart;

    关于reactjs - 如何以 useContext 作为依赖项正确使用 useEffect,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69289935/

    31 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com