https://innovatorwhy.tistory.com/40
위와 달리 window history의 api와 recoil을 활용하면
코드를 간결하게 사용하여 modal을 back버튼으로 제어 할 수 있습니다.
주요 개념은 아래와 같습니다.
먼저, stack을 관리할 Recoil Atom을 생성합니다.
const stackState = atom({
key: '@stack',
default: [],
});
배열에 해당 모달을 추가하는 custom hook을 생성합니다.
custom hook에서는 다음과 같은 일을 합니다.
1. 배열에 요소를 삽입합니다.
type: string;
setState: (_: boolean) => void; 해당 modal의 show/hide state를 false로 변경시켜주기 위해사용
2. window history state를 push 해서 broweser의 back키를 작동하게 합니다.
※ history.pushState(state, title[, url])
const usePush = () => {
const [stack, setStack] = useRecoilState(stackState);
const push = (type: string, setState: (_: boolean) => void) => {
const el = { type: type, setState };
setStack(
produce(stack, (draft) => {
draft.push(el);
})
);
history.pushState({ type }, type);
};
return push;
};
배열에 해당 모달을 제거하는 custom hook을 생성합니다.
const usePop = () => {
const [stack, setStack] = useRecoilState(stackState);
const popStack = () => {
if (stack.length) {
setStack(
produce(stack, (draft) => {
const el = draft.pop();
el?.setState(false);
})
);
}
};
return popStack;
};
Modal show/hide 상태에따라 해당 Stack 배열에 추가합니다.
※ 여기서는 별도의 custom hook을 만들어 간소화 하였습니다.
export const useLayeredStack = (isShowState?: boolean, setShowState?: any) => {
const pushModal = usePush();
useEffect(() => {
if (isShowState) {
pushModal('modal', setShowState);
}
}, [isShowState, setShowState]);
};
window onpopstate 이벤트 핸들러에서 stack에서 요소 하나를 제거하는 custom hook을 실행합니다.
const popStack = usePop();
window.onpopstate = () => {
isBack = true;
popStack();
};
실제 해당 Modal을 관리하는 Component에서 custom hook을 사용하여 간단하게
back버튼으로 해당 Modal의 state를 관리할 수 있습니다.
const [isShow, setShow] = useState(false);
useLayeredStack(isShow, setShow);
...
{isShow && <Modal />}
React + immer 를 사용한 불변성 관리 (feat. recoil) (0) | 2023.02.18 |
---|---|
Styled-components props 전달 (0) | 2023.02.18 |
[React] Back 버튼으로 Modal 제어하기(1) (0) | 2023.02.07 |
React forwardRef - (feat. 공통 팝업) (0) | 2023.02.01 |
React Transition Modal 적용 (0) | 2023.01.27 |
댓글 영역