[React] 학습 - day9

jiseong·2021년 9월 24일
0

T I Learned

목록 보기
81/291
post-custom-banner

모달창

위의 버튼을 클릭 시, 모달창을 보이기 위해서 모달창을 키고 끄는 상태를 관리하는 state를 생성했다.

그리고 Modal 컴포넌트에게 해당 state를 전달하여 state값에 따라 렌더링의 변화를 주게끔하였고 모달창을 닫을 수 있는 함수를 전달하는 방식으로 구현하였다.

function DetailImageModalCotainer() {
  const [modalState, setModalState] = useState(false);
  function onClose() {
    setModalState(false);
  }

  function onOpen() {
    setModalState(true);
  }

  return (
    <>
      <AllImgBtn onOpen={onOpen} />
      <Modal modalState={modalState} onClose={onClose} width={'70vw'} height={'80vh'}>
        <div>JSX 태그 안</div>
        <div>children prop</div>
      </Modal>
    </>
  );
}

children prop

<Modal> JSX 태그 안에 있는 것들은 Modal 컴포넌트의 children prop으로 전달되어 아래와 같은 방식으로 Modal 컴포넌트에서 전달받아 출력할 수 있다.

function Modal({ modalState, onClose, children, width, height }) {
  if (!modalState) return null;

  return (
    <div css={modalBackground}>
      <div css={modalContainer({ width, height })}>
        <a onClick={onClose} css={closeBtn}>
          &#10094;
        </a>
        {children}
      </div>
    </div>
  );
}

state 업데이트와 eventlistener

모달 창의 바깥 범위를 클릭 했을 때 modalState 값에 따라 모달창을 닫아주기 위해 eventlistener를 사용하며 알게 된 사실이다.

const [modalState, setModalState] = useState(false);

function handleClick(e) {
  console.log(modalState);
}

useEffect(() => {
  window.addEventListener('click', handleClick);
  return () => {
    window.removeEventListener('click', handleClick);
  };
}, []);

위의 방식대로 하게 되면 modalState값이 어떤 동작에 의해 true로 변경되었을 때 클릭 이벤트시 호출되는 handleClick함수에서 로그로 찍히는 값은 항상 false이다.
이는 JS에서의 클로저 때문이다.

이를 수정하기 위해서는 아래 코드와 같이 modalState값이 업데이트 되었을 때마다 핸들러를 새롭게 등록시켜줘야 원하는 state 값을 얻을 수 있다.

const [modalState, setModalState] = useState(false);

function handleClick(e) {
  console.log(modalState);
}

useEffect(() => {
  window.addEventListener('click', handleClick);
  return () => {
    window.removeEventListener('click', handleClick);
  };
}, [modalState]);
post-custom-banner

0개의 댓글