Skip to content

Commit

Permalink
feat: useUrlParamSync
Browse files Browse the repository at this point in the history
  • Loading branch information
junghyeonsu committed Sep 12, 2024
1 parent e00fc8b commit 4964aa8
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 5 deletions.
32 changes: 27 additions & 5 deletions component-docs/src/components/ProgressCircleControls.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,41 @@
import * as React from "react";

import { BoxButton } from "@/seed-design/ui/box-button";
import { useUrlParamSync } from "@/src/hooks/useUrlParamSync";
import {
useProgressCircleActions,
useProgressCircleDuration,
useProgressCircleEasing,
} from "@/src/stores/progress-circle";

import { useRouter } from "next/router";
import * as css from "./ProgressCircleControls.css";

export const ProgressCircleControls = () => {
const { set } = useProgressCircleActions();
const router = useRouter();

const storeDuration = useProgressCircleDuration();
const storeEasing = useProgressCircleEasing();

const [duration, setDuration] = useUrlParamSync({
paramName: "duration",
storeValue: storeDuration,
setStoreValue: (value) => set({ duration: value }),
});

const [easing, setEasing] = useUrlParamSync({
paramName: "easing",
storeValue: storeEasing,
setStoreValue: (value) => set({ easing: value }),
});

const setAll = () => {
set({ duration, easing });

const [duration, setDuration] = React.useState(useProgressCircleDuration());
const [easing, setEasing] = React.useState(useProgressCircleEasing());
const params = new URLSearchParams();
params.set("duration", duration);
params.set("easing", easing);
router.push(`?${params.toString()}`);
};

return (
<div>
Expand Down Expand Up @@ -56,7 +78,7 @@ export const ProgressCircleControls = () => {
onChange={(e) => setEasing(e.target.value)}
/>
</div>
<BoxButton type="button" onClick={() => set({ duration, easing })}>
<BoxButton type="button" onClick={setAll}>
적용
</BoxButton>
</div>
Expand Down
39 changes: 39 additions & 0 deletions component-docs/src/hooks/useUrlParamSync.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// hooks/useUrlParamSync.ts
import { useEffect, useState } from "react";
import { useSearchParams } from "next/navigation";

type SetStateAction<T> = T | ((prevState: T) => T);
type SetStateFunction<T> = (value: SetStateAction<T>) => void;

interface UrlParamSyncOptions<T> {
paramName: string;
storeValue: T;
setStoreValue: (value: T) => void;
parse?: (value: string) => T;
}

export function useUrlParamSync<T>({
paramName,
storeValue,
setStoreValue,
parse = (value: string) => value as unknown as T,
}: UrlParamSyncOptions<T>): [T, SetStateFunction<T>] {
const searchParams = useSearchParams();
const [localValue, setLocalValue] = useState<T>(storeValue);

// biome-ignore lint/correctness/useExhaustiveDependencies: <explanation>
useEffect(() => {
const paramValue = searchParams.get(paramName);
if (paramValue) {
const parsedValue = parse(paramValue);
setLocalValue(parsedValue);
setStoreValue(parsedValue);
}
}, [searchParams]);

useEffect(() => {
setLocalValue(storeValue);
}, [storeValue]);

return [localValue, setLocalValue];
}

0 comments on commit 4964aa8

Please sign in to comment.