refactor: rename variables and create hooks

Signed-off-by: Chloe <pinkcloudvnn@gmail.com>
This commit is contained in:
Chloe 2024-05-08 08:38:44 +07:00
parent a41b3e565f
commit be494b489c
No known key found for this signature in database
GPG Key ID: CFD53CE570D42DF5
3 changed files with 62 additions and 51 deletions

View File

@ -82,11 +82,11 @@ const constructFilterInput = (filters: {
}
if (filters[`${PRICE_FILTER_ID}.max`]) {
price.max = Number(filters[`${PRICE_FILTER_ID}.max`]);
!price.min && (price.min = 0);
}
if (price.max && !price.min) {
price.min = 0;
}
if (price.max || price.min) {
results.push({ price });
}
return results;
};

View File

@ -1,6 +1,7 @@
'use client';
import Price from 'components/price';
import { useDebounce } from 'hooks';
import { Filter } from 'lib/shopify/types';
import { createUrl } from 'lib/utils';
import get from 'lodash.get';
@ -16,21 +17,6 @@ const currencySymbol =
.formatToParts(1)
.find((part) => part.type === 'currency')?.value || '$';
const useDebounce = (value: string, delay = 500) => {
const [debouncedValue, setDebouncedValue] = useState('');
const timerRef = useRef<ReturnType<typeof setTimeout>>();
useEffect(() => {
timerRef.current = setTimeout(() => setDebouncedValue(value), delay);
return () => {
clearTimeout(timerRef.current);
};
}, [value, delay]);
return debouncedValue;
};
const PriceRange = ({ id, values }: { id: string; values: Filter['values'] }) => {
const highestPrice = values.reduce(
(acc, { value }) => Math.max(acc, get(value, 'price.max', 0)),
@ -41,76 +27,85 @@ const PriceRange = ({ id, values }: { id: string; values: Filter['values'] }) =>
const pathname = usePathname();
const router = useRouter();
const priceMin = searchParams.get(`${id}.min`);
const priceMax = searchParams.get(`${id}.max`);
const initialPriceMin = searchParams.get(`${id}.min`);
const initialPriceMax = searchParams.get(`${id}.max`);
const [min, setMin] = useState(priceMin || '');
const [max, setMax] = useState(priceMax || '');
const [minPrice, setMinPrice] = useState(initialPriceMin || '');
const [maxPrice, setMaxPrice] = useState(initialPriceMax || '');
const debouncedMin = useDebounce(min);
const debouncedMax = useDebounce(max);
const debouncedMinPrice = useDebounce(minPrice);
const debouncedMaxPrice = useDebounce(maxPrice);
const minRef = useRef(min);
const maxRef = useRef(max);
const minPriceRef = useRef(minPrice);
const maxPriceRef = useRef(maxPrice);
const updateSearchParams = useCallback(
(priceRange: { min: string; max: string }) => {
const newSearchParams = new URLSearchParams(searchParams);
if (!priceRange.min) {
newSearchParams.delete(`${id}.min`);
} else {
newSearchParams.set(`${id}.min`, priceRange.min);
}
if (!priceRange.max) {
newSearchParams.delete(`${id}.max`);
} else {
newSearchParams.set(`${id}.max`, priceRange.max);
}
router.replace(createUrl(pathname, newSearchParams), { scroll: false });
},
[id, pathname, router, searchParams]
);
const handleChangeMinPrice = (value: string) => {
setMin(value);
minRef.current = value;
setMinPrice(value);
minPriceRef.current = value;
};
const handleChangeMaxPrice = (value: string) => {
setMax(value);
maxRef.current = value;
setMaxPrice(value);
maxPriceRef.current = value;
};
useEffect(() => {
if (debouncedMin) {
let _minPrice = debouncedMin;
if (debouncedMinPrice) {
let _minPrice = debouncedMinPrice;
const minNum = Number(_minPrice);
if (minNum < 0) {
_minPrice = '0';
}
if (maxRef.current && minNum > Number(maxRef.current)) {
_minPrice = maxRef.current;
if (maxPriceRef.current && minNum > Number(maxPriceRef.current)) {
_minPrice = maxPriceRef.current;
}
if (minNum > highestPrice) {
_minPrice = String(highestPrice);
}
if (_minPrice !== debouncedMin) {
if (_minPrice !== debouncedMinPrice) {
handleChangeMinPrice(_minPrice);
}
updateSearchParams({ min: _minPrice, max: maxRef.current });
updateSearchParams({ min: _minPrice, max: maxPriceRef.current });
} else {
updateSearchParams({ min: '', max: maxRef.current });
updateSearchParams({ min: '', max: maxPriceRef.current });
}
}, [debouncedMin, highestPrice, updateSearchParams]);
}, [debouncedMinPrice, highestPrice, updateSearchParams]);
useEffect(() => {
if (debouncedMax) {
let _maxPrice = debouncedMax;
if (debouncedMaxPrice) {
let _maxPrice = debouncedMaxPrice;
const maxNum = Number(_maxPrice);
if (minRef.current && maxNum < Number(minRef.current)) {
_maxPrice = minRef.current;
if (minPriceRef.current && maxNum < Number(minPriceRef.current)) {
_maxPrice = minPriceRef.current;
}
if (maxNum > highestPrice) {
_maxPrice = String(highestPrice);
}
if (_maxPrice !== debouncedMax) {
if (_maxPrice !== debouncedMaxPrice) {
handleChangeMaxPrice(_maxPrice);
}
updateSearchParams({ min: minRef.current, max: _maxPrice });
updateSearchParams({ min: minPriceRef.current, max: _maxPrice });
} else {
updateSearchParams({ min: minRef.current, max: '' });
updateSearchParams({ min: minPriceRef.current, max: '' });
}
}, [debouncedMax, highestPrice, updateSearchParams]);
}, [debouncedMaxPrice, highestPrice, updateSearchParams]);
return (
<div className="flex flex-col">
@ -126,7 +121,7 @@ const PriceRange = ({ id, values }: { id: string; values: Filter['values'] }) =>
min={0}
max={highestPrice}
placeholder="From"
value={min}
value={minPrice}
onChange={(e) => handleChangeMinPrice(e.target.value)}
/>
</div>
@ -135,10 +130,10 @@ const PriceRange = ({ id, values }: { id: string; values: Filter['values'] }) =>
<input
className="w-28 rounded border-none text-sm focus:ring-0 focus:ring-offset-0"
type="number"
min={min}
min={minPrice}
max={highestPrice}
placeholder="To"
value={max}
value={maxPrice}
onChange={(e) => handleChangeMaxPrice(e.target.value)}
/>
</div>

16
hooks/index.tsx Normal file
View File

@ -0,0 +1,16 @@
import { useEffect, useRef, useState } from 'react';
export const useDebounce = (value: string, delay = 500) => {
const [debouncedValue, setDebouncedValue] = useState('');
const timerRef = useRef<ReturnType<typeof setTimeout>>();
useEffect(() => {
timerRef.current = setTimeout(() => setDebouncedValue(value), delay);
return () => {
clearTimeout(timerRef.current);
};
}, [value, delay]);
return debouncedValue;
};