mirror of
https://github.com/vercel/commerce.git
synced 2025-06-06 08:16:59 +00:00
70 lines
1.6 KiB
TypeScript
70 lines
1.6 KiB
TypeScript
'use client';
|
|
|
|
import { useRouter, useSearchParams } from 'next/navigation';
|
|
import { useMemo, useOptimistic } from 'react';
|
|
|
|
type ProductState = {
|
|
[key: string]: string;
|
|
} & {
|
|
image?: string;
|
|
};
|
|
|
|
type UseProductResult = {
|
|
state: ProductState;
|
|
updateOption: (name: string, value: string) => ProductState;
|
|
updateImage: (index: string) => ProductState;
|
|
};
|
|
|
|
export function useProduct(): UseProductResult {
|
|
const searchParams = useSearchParams();
|
|
|
|
const getInitialState = () => {
|
|
const params: ProductState = {};
|
|
for (const [key, value] of searchParams.entries()) {
|
|
params[key] = value;
|
|
}
|
|
return params;
|
|
};
|
|
|
|
const [state, setOptimisticState] = useOptimistic(
|
|
getInitialState(),
|
|
(prevState: ProductState, update: ProductState) => ({
|
|
...prevState,
|
|
...update
|
|
})
|
|
);
|
|
|
|
const updateOption = (name: string, value: string) => {
|
|
const newState = { [name]: value };
|
|
setOptimisticState(newState);
|
|
return { ...state, ...newState };
|
|
};
|
|
|
|
const updateImage = (index: string) => {
|
|
const newState = { image: index };
|
|
setOptimisticState(newState);
|
|
return { ...state, ...newState };
|
|
};
|
|
|
|
return useMemo(
|
|
() => ({
|
|
state,
|
|
updateOption,
|
|
updateImage
|
|
}),
|
|
[state]
|
|
);
|
|
}
|
|
|
|
export function useUpdateURL() {
|
|
const router = useRouter();
|
|
|
|
return (state: ProductState) => {
|
|
const newParams = new URLSearchParams(window.location.search);
|
|
Object.entries(state).forEach(([key, value]) => {
|
|
newParams.set(key, value);
|
|
});
|
|
router.push(`?${newParams.toString()}`, { scroll: false });
|
|
};
|
|
}
|