I save product ids in a localstorage to be used in recently viewed component. My Recently viewed component is below
import { useQuery } from "@apollo/client";
import { getRecentlyViewedProductArr } from "@gb-utils/product/product"
import { RECENTLY_VIEWED } from "@gb-utils/queries/product";
import { useEffect, useState } from "react";
export default function RecentlyViewed() {
const [recentIds, setRecentIds] = useState([])
const { loading, error, data } = useQuery(RECENTLY_VIEWED, {
variables: { ids: recentIds }
})
useEffect(() => {
setRecentIds(getRecentlyViewedProductArr())
}, []);
if (loading) {
return 'Loading';
}
if (error) {
return error.message
}
return (
<div>{JSON.stringify(data)}</div>
)
}
My question is about how I use get the product from wp-graphql using userQuery with the local storage.
Currently I am defining a state to store product ids and on mount of the RecentlyViewed component I update the recentIds by getting the data from localstorage. Is there a better way of doing the code above because I feel like it fetching data from wp without or empty recentIds is a problem.
helper.js
export const addRecentlyViewedProduct = (productId) => {
let recent = getRecentlyViewedProduct()
if (isEmpty(recent)) {
// If recently viewed is empty then we just save the product id
saveRecentlyViewedProduct(productId)
return getRecentlyViewedProduct()
}
// if not empty then we check if product id exist and remove
if (recent.includes(productId)) {
recent = recent.replace(productId, '')
}
// Since we remove the product then we Add the product id again
recent = "".concat(productId, '|', recent)
recent = recent.replace('||', '|');
recent = recent.startsWith('|') ? recent.substring(1) : recent
recent = recent.endsWith('|') ? recent.substring(0, recent.length - 1) : recent;
const limit = 5;
let recentProductIds = recent.split('|')
if (recentProductIds.length > limit) {
recentProductIds = recentProductIds.slice(0, limit)
}
saveRecentlyViewedProduct(recentProductIds.join('|'))
return getRecentlyViewedProduct()
}
export const saveRecentlyViewedProduct = (value) => {
return localStorage.setItem('woo-next-recent-product', value);
}
export const getRecentlyViewedProduct = () => {
const recentProductsStr = localStorage.getItem('woo-next-recent-product')
return recentProductsStr
}
export const getRecentlyViewedProductArr = () => {
const recentProductsStr = getRecentlyViewedProduct()
if (isEmpty(recentProductsStr)) {
return ''
}
let recentProductIds = recentProductsStr.split('|')
return Array.from(recentProductIds.slice(1), Number); // get the 2nd to the last element
}
You can use the skip
option from the useQuery
API: https://www.apollographql.com/docs/react/data/queries/#skip
const [recentIds, setRecentIds] = useState([])
const { loading, error, data } = useQuery(RECENTLY_VIEWED, {
variables: { ids: recentIds },
skip: recentIds.length === 0
})
useEffect(() => {
setRecentIds(getRecentlyViewedProductArr())
}, []);