如何在地图函数中调用 useQuery?
How do I call useQuery in a map function?
我有以下反应组件,它根据购物车中的商品从 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 函数添加为内部函数,但这也无济于事。我该如何解决这个问题?
需要在每次渲染时调用挂钩以确保确定性一致,React 会在每次构建时检查这一点(并在检测到时抛出错误)。如果钩子不在 React 组件的 top/main 调用堆栈中,您可能会遇到问题。
您可以做的是创建另一个在您的地图函数中呈现的 React 组件。这个 React 组件不需要渲染任何东西,你可以只添加你的代码和 return null
.
尝试在您的组件上方添加:
function EditProduct({ x ) {
const [editProduct] = useMutation(queries.EDIT_PRODUCT);
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} />)
请注意,在满足您的 if else
条件的每个 AddOrder
渲染中,EditProduct
组件将 re-render,这将调用挂钩并可能导致意外后果(例如,如果以这种方式设计挂钩,则多次发出相同的获取请求)。我没有使用过你的特定钩子,所以我不能肯定地说,但这是需要考虑的事情。
我有以下反应组件,它根据购物车中的商品从 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 函数添加为内部函数,但这也无济于事。我该如何解决这个问题?
需要在每次渲染时调用挂钩以确保确定性一致,React 会在每次构建时检查这一点(并在检测到时抛出错误)。如果钩子不在 React 组件的 top/main 调用堆栈中,您可能会遇到问题。
您可以做的是创建另一个在您的地图函数中呈现的 React 组件。这个 React 组件不需要渲染任何东西,你可以只添加你的代码和 return null
.
尝试在您的组件上方添加:
function EditProduct({ x ) {
const [editProduct] = useMutation(queries.EDIT_PRODUCT);
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} />)
请注意,在满足您的 if else
条件的每个 AddOrder
渲染中,EditProduct
组件将 re-render,这将调用挂钩并可能导致意外后果(例如,如果以这种方式设计挂钩,则多次发出相同的获取请求)。我没有使用过你的特定钩子,所以我不能肯定地说,但这是需要考虑的事情。