代码之家  ›  专栏  ›  技术社区  ›  Tom Brooke

如何在映射函数中调用useQuery?

  •  0
  • Tom Brooke  · 技术社区  · 2 年前

    我有下面的react组件,它根据购物车中的商品从mongodb集合中删除产品。我在运行代码时出现以下错误:

    组成部分:

     function AddOrder() {
        const d = new Date();
        let text = d.toString();
        const { currentUser } = useContext(AuthContext);
    
        const { data, loading, error } = useQuery(queries.GET_USER_BY_ID, {
            fetchPolicy: "network-only",
            variables: {
                id: currentUser.uid,
            },
        });
    
        const getUserOrders = useQuery(queries.GET_USER_ORDERS, {
            fetchPolicy: "network-only",
            variables: {
                userId: currentUser.uid,
            },
        });
    
        const [addOrder] = useMutation(queries.ADD_ORDER);
       
        const [editProduct] = useMutation(queries.EDIT_PRODUCT);
        
    
        if (error) {
            return <h1> error</h1>;
        } else if (loading) {
            return <h1> loading</h1>;
        } else if (data && getUserOrders.data && currentUser && data.getUser.cart.length > 0) {
            let newCart = [];
            for (let i = 0; i < data.getUser.cart.length; i++) {
                newCart.push({ quantity: data.getUser.cart[i].quantity, _id: data.getUser.cart[i]._id });
            }
    
            addOrder({
                variables: {
                    userId: currentUser.uid,
                    status: "ordered",
                    createdAt: text,
                    products: newCart,
                    flag: getUserOrders.data.userOrders.length + 1,
                },
            });
            
            newCart.map((x) => {
                let getProd = useQuery(queries.GET_PRODUCTS_BY_ID, {
                    fetchPolicy: "network-only",
                    variables: {
                        _id : x._id
                    },
                });
                let a = getProd.quantity -x.quantity
                editProduct({
                    variables: {
                        _id : x._id,
                        quantity: a
                    },
                });
            })
        
        }
    }
    export default AddOrder;
    

    我得到的错误是:

    React Hook "useQuery" cannot be called inside a callback. React Hooks must be called in a React function component or a custom React Hook function
    

    我试图将map函数添加为一个内部函数,但也没用。我该怎么解决这个问题?

    1 回复  |  直到 2 年前
        1
  •  1
  •   Steve Hynding    2 年前

    需要在每个渲染上调用钩子,以确定一致性,并在每个构建上对此进行反应检查(检测到时抛出错误)。如果挂钩不在React组件的顶部/主调用堆栈中,则可能会出现问题。

    可以做的是创建另一个React组件,该组件在map函数中渲染。这个React组件不需要呈现任何内容,您只需添加代码并返回即可 null .

    尝试在组件上方添加以下内容:

    function EditProduct = ({ x ) => {
      let getProd = useQuery(queries.GET_PRODUCTS_BY_ID, {
        fetchPolicy: "network-only",
        variables: {
          _id : x._id
        },
      });
      let a = getProd.quantity -x.quantity
      editProduct({
        variables: {
          _id : x._id,
          quantity: a
        },
      });
      return null;
    }
    

    然后将地图使用情况更新为:

    newCart.map((x) => <EditProduct x={x} />)
    

    在每一次渲染 AddOrder 这符合你的要求 if else 条件,条件 EditProduct 组件将重新呈现,这将调用钩子,并可能导致意外后果(例如,如果钩子是以这种方式设计的,则多次发出相同的获取请求)。我还没有用过你的钩子,所以我不能肯定,但这是需要考虑的。