728x90

https://www.youtube.com/watch?v=NwLWX2RNVcw 

위 영상을 보고 언젠가 데이터를 관리할 때, 퍼널형식으로 보여주면 효율적인  랜더링이 가능하지 않을까 생각했다.

 

 

 

HOUS-SG 프로젝트에서는 숙소등록하는 부분이 있다.
해당 페이지에서 우선 유저는 이미지 제출을 통해 사업자 등록증을 검사를 받는다.

이후 숙소 위치를 다음 우편번호 기능을 통해서 제출한다.

마지막으로 숙소와 관련된 추가정보를 제출한다.

 

결국 숙소 등록 마지막에 사업자 정보, 주소, 숙소정보를 제출하는데 중간중간 기능이 너무 많다. 이를 한페이지에서 관리하려다 보니 복잡하다고 생각했고, 퍼널형식으로 나누는 방식을 도입하려고 했다.

 

토스 라이브러리에 있는 useFunnel 을 사용하면 조금 더 쉬웠겠지만, 유사 기능을 직접 구현해보고자 하였다.

 

 

현재 구성은 아래와 같다.

이를 다음과 같은 상태로 바꾸려 한다.

const OwnerHouseRegister = () => {
	const navigate = useNavigate();

	useWindowWarning();

	const location = useLocation();
	const funnelState = location.state;

	const step = funnelState ? funnelState.step : 0;
	const goStep = (step: number, newState?: { [key: string]: string | number }) => {
		navigate('', { state: { ...funnelState, step, ...newState } });
	};

	return (
		<RegisterWrapper>
			{step === 0 && <BusinessRegi goStep={goStep} step={step} funnelState={funnelState} />}
			{step === 1 && <AddressFinder goStep={goStep} step={step} funnelState={funnelState} />}
			{step === 2 && <HouseImageRegi goStep={goStep} step={step} funnelState={funnelState} />}
			{step === 3 && <HouseInfoRegi goStep={goStep} step={step} funnelState={funnelState} />}
			<div onClick={() => goStep(0)}>등록완료</div>
		</RegisterWrapper>
	);
};

export default OwnerHouseRegister;

 

토스측 진유림님이 말했던 데로, 유저가 페이지 이동을 uri 부근의  뒤로 가기 버튼으로도 할 수 있기 때문에, 단순한 state로 관리하는 것이 아니라, navigate를 통해서 관리하려고 했다.

 

이 부분에서 처음에 어려움을 겪었는데

1. 유튜브 영상에 있는 shallow routing은  next.js의 기능이다.

2. 구글링 결과 현재 history 훅은 deprecated 되었기 때문에, navigate 기능을 자의적 해석을 통해 해당 기능을 구현해야 했다.

 

결국 next.js 또한 리액트 기반의 프레임워크 이기에 나도 구현할 수 있지 않을까?라는 의문에 끝까지 시도했다.

 

목표는 토스측에서 설정한 목표에서 아직 훅으로 만드는 부분만 구현하지 못했다.

 

따라서 나의 목표는

 

1. step을 통해서 랜더링 관리

2. 유저가 뒤로가기등 페이지 이동 기능을 사용하여도 state가 사라지지 않게 하기.

3. 그렇다고 데이터를 uri 에 노출시켜서 유저 임의로 수정하지 못하게 하기

 

 

 

이를 navigate의 state를 활용하여 구현하려고 한다.

 

navigate의 두번째 매개변수를 통해서 추가적인 설정을 할 수 있는데 해당 매개변수의 키값으로 state를 줄 경우에 값을 저장할 수 있다. 이를 통해서 페이지 이동할 떄, 값을 주고 받을 수 있는데... 해당 값이 뒤로가기 버튼을 눌렀을 때 사라지는  문제점이 있다.

 

이를 해결하기 위해서 전역변수를 써야 하나 고민을 했지만, 그럴 경우 진유림님(??) 이 말하신 대로 데이터의 추적이 복잡해질 수 있다.

 

따라서 나는 왜 뒤로가기 버튼을 누르면 데이터가 사라질 까 고민했고, 뒤로가기 버튼 클릭시 적용되던 이벤트를 제거하고자 했다.

이를 위해 작성한 훅이 useSaveNavigateState이다. 

import { useEffect } from 'react';
import { removeWindowWarningState, windowWarningState } from '../utils';

const useSaveNavigateState = () => {
	useEffect(() => {
		windowWarningState();

		return () => {
			removeWindowWarningState();
		};
	}, []);
	return null;
};

export default useSaveNavigateState;

 

const windowWarningState = () => {
	window.addEventListener('popstate', popstateHandler);
};

const removeWindowWarningState = () => {
	window.removeEventListener('popstate', popstateHandler);
};

const popstateHandler = (event: PopStateEvent) => {
	event.preventDefault(); // 뒤로가기 이벤트의 기본 동작을 막음
};

export { windowWarningState, removeWindowWarningState };

 

 

이후 location 내에 저장된 state를 가져오고, 페이지 이동할 때는 전개연산자를 통해서 state를 업데이트를 하는 방식으로 페이지 이동을 구현하였다!.

 

추후 훅을 통해 업데이트 해보겠습니다

 

참고

https://reactrouter.com/en/main/hooks/use-navigation

 

useNavigation v6.22.3 | React Router

useNavigation This hook tells you everything you need to know about a page navigation to build pending navigation indicators and optimistic UI on data mutations. Things like: Global loading indicators Disabling forms while a mutation is happening Adding bu

reactrouter.com

 

피드백 (2024.03.25)

그 당시에는 최대한 지역적인 상태로 관리하는게 좋다고 막연하게 생각했었는데, 아쉬웠던 점도 공유하고자 추가로 작성합니다.

 

1. step ===0 ~~~ 이런식으로 비슷한 형식의 코드들인데, 이를  토스 영상처럼 compound패턴을 도입 못한점이 아쉬웠습니다.

2. 결국 저희 로직대로라면 사업자는 한번에 숙소등록을 해야합니다. 2단계 까지 진행하고 브라우저를 종료해도, 다시 1단계 부터 진행해야합니다. 차라리 단계마다 미리 백엔드와 통신을 하여서, 현재 기록된 내용들을 바탕으로 스탭을 구별한다면, ( 사업자 번호가 있다면 2단계 완료)  좀 더 UX가 향상될 것이라고 느꼈습니다.

+ Recent posts