I am using Apollo for graphQL queries in a NextJS project I have the following request. I feel like the solution to this is simple, but the error occurs at the stateData.allProducts
section it is saying it is null, but I have set the state in the useEffect and it has data
as a dependency in the array, so shouldn't it re-render once data has loaded.
This is all works just fine if I placed these checks below a if statement checking the loading and return ...loading
but then I can't use useEffect.
Any help as to what I am doing wrong would be greatly appreciated.
Thanks!
const { data, loading, error } = useQuery(QUERY);
const Router = useRouter();
// Creating state and setting it from query
const [stateData, setStateData] = useState(null);
const [disableAddToCart, setDisableAddToCart] = useState(false);
useEffect(() => {
setStateData(data);
}, [data]);
//~~~~~~~// <--- RIGHT HERE IS WHERE I GET THE NULL ERROR
const productFound = stateData.allProduct.find(
(product: any) => product.slug.current === Router.query.product
);
const currentItem = cartDetails[productFound.id];
useEffect((): void => {
console.log("currentItem", currentItem);
if (currentItem) {
if (currentItem.quantity > 0) {
setDisableAddToCart(true);
} else {
setDisableAddToCart(false);
}
}
}, [currentItem]);
CodePudding user response:
As long as your query is loading, or if there is an error, the data
variable from useQuery
will be null
.
Therefore you have to check for the loading
to have finished and that no error
has occurred. And/or for the data
to be defined.
Also, stateData
is unnecessary, because data
is already a ready-to-use state variable.
const { data, loading, error } = useQuery(QUERY);
const Router = useRouter();
const [disableAddToCart, setDisableAddToCart] = useState(false);
let productFound;
let currentItem;
if(!loading && !error && data?.allProduct){
productFound = data.allProduct.find(
(product: any) => product.slug.current === Router.query.product
);
currentItem = cartDetails[productFound.id];
}
useEffect((): void => {
//since you are using typescript, you can use the optional chaining operator
if (currentItem?.quantity > 0) {
setDisableAddToCart(true);
} else {
setDisableAddToCart(false);
}
}, [currentItem]);