useStepState
useStep 을 확장해 multi-step process
의 step
을 관리 및 추적하며 동시에 내부 상태
를 관리 할 수 있는 커스텀 훅입니다.
storageOptions
를 활용해 setState
시에 브라우저 스토리지(sessionStorage
, localStorage
)에 상태를 저장 할 수 있습니다.
clearState
는 state를 null
로 초기화합니다. storageOptions
가 있을 경우 해당 options
에 대응하는 스토리지 데이터를 제거합니다.
Code
Interface
typescript
interface StorageOptions {
key: string;
type: 'localStorage' | 'sessionStorage';
}
interface UseStepWithInitialState<T> extends UseStepProps {
initialState: T;
storageOptions?: StorageOptions;
}
interface UseStepWithoutInitialState extends UseStepProps {
storageOptions?: StorageOptions;
}
typescript
// 함수 오버로딩
export function useStepState<T>({
initialState,
...props
}: UseStepWithInitialState<T>): ReturnType<typeof useStep> & {
readonly state: T;
readonly setState: (newState: SetStateAction<T>) => void;
readonly clearState: () => void;
};
export function useStepState<T>(props: UseStepWithoutInitialState): ReturnType<
typeof useStep
> & {
readonly state: T | null;
readonly setState: (newState: SetStateAction<T | null>) => void;
readonly clearState: () => void;
};
Usage
typescript
import { useStepState } from '@modern-kit/react';
export const Example = () => {
const { state, setState, clearState, currentStep, goToNextStep, goToPrevStep } =
useStepState({
maxStep: 2,
initialState: { name: '' },
storageOptions: { key: 'stepState', type: 'sessionStorage' },
});
const handleGoToNextStep = () => {
goToNextStep(({ prevStep, nextStep }) => {
console.log(`${prevStep}에서 ${nextStep}로 이동`);
setState({ name: 'bar' });
});
};
const handleGoToPrevStep = () => {
goToPrevStep(({ prevStep, nextStep }) => {
console.log(`${prevStep}에서 ${nextStep}로 이동`);
setState({ name: 'foo' });
});
};
const boxStyle = {
width: '300px',
height: '120px',
fontSize: '21px',
};
return (
<div>
<div>
<button onClick={handleGoToPrevStep}>이전 스탭</button>
<button onClick={handleGoToNextStep}>다음 스탭</button>
<button onClick={clearState}>상태 초기화</button>
</div>
<div>
<p>currentStep: {currentStep}</p>
<p>state: {JSON.stringify(state)}</p>
</div>
<div>
{currentStep === 1 && (
<div style={{ ...boxStyle, backgroundColor: 'red' }}>
1번 Step Box
</div>
)}
{currentStep === 2 && (
<div style={{ ...boxStyle, backgroundColor: 'green' }}>
2번 Step Box
</div>
)}
</div>
</div>
);
};
Example
currentStep: 0
state: {"name":""}
Best Practice
- 브라우저 새로고침 시 상태를 적절하게 유지하고 싶다면
queryString
과react-router-dom
을 함께 사용하는 것을 권장합니다.
import { useStepState } from '@modern-kit/react';
import { useNavigate } from 'react-router-dom'
import qs from 'query-string'
const Example = () => {
const parsedStorage = JSON.parse(sessionStorage.getItem('stepState'));
const parsedQuery = qs.parse(location.search);
const navigate = useNavigate();
const { state, setState, goToNextStep, goToPrevStep } = useStepState({
maxStep: 5,
initialState: parsedStorage,
initialStep: parsedQuery.step,
storageOptions: { key: 'stepState', type: 'sessionStorage' },
});
const handleGoToNextStep = () => {
goToNextStep(({ nextStep }) => {
setState({
/* ... */
});
navigate(`/test?step=${nextStep}`);
});
};
const handleGoToPrevStep = () => {
goToNextStep(({ nextStep }) => {
setState({
/* ... */
});
navigate(`/test?step=${nextStep}`);
});
};
// ...
return (
// ...
);
};