상세 컨텐츠

본문 제목

[React] Back 버튼으로 Modal 제어하기(2)

React

by 일단두잇 2023. 2. 9. 17:59

본문

반응형

https://innovatorwhy.tistory.com/40

 

[React] Back 버튼으로 Modal 제어하기(1)

Android에서는 물리적인 Back 버튼이 존재합니다. 따라서, Hybrid Web 개발시 해당 버튼의 액션을 고려해야 합니다. 고려해야하는 경우는 팝업이나 Toast UI 같은 화면 위에 뜨는 팝업 즉, Layer 팝업이 열

innovatorwhy.tistory.com

 

위와 달리 window history의 api와 recoil을 활용하면

코드를 간결하게 사용하여 modal을 back버튼으로 제어 할 수 있습니다.

 

주요 개념은 아래와 같습니다.

 

  1. Modal과 같은 Layered Element들을 배열로 관리합니다.
  2. 해당 Modal을 관리하는 화면에서 사용할 수 있는 custom hook을 생성합니다.
  3. onpopstate 이벤트에서 해당 요소를 제거하고 해당 요소의 state을 변경합니다.
 

먼저, 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을 생성합니다.

  1. 배열에서 마지막 element를 제거합니다.
  2. 제거한 element의 setState를 호출하여 modal의 show state를 변경하여 모달을 닫도록 합니다.
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 />}
 

 

 

 

 

반응형

관련글 더보기

댓글 영역