Home > database >  UseQuery graphql -> useState with useEffect such that I can run second useEffect to set more stat
UseQuery graphql -> useState with useEffect such that I can run second useEffect to set more stat

Time:03-26

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]);
  • Related