두피만
FE 던지기
두피만
전체 방문자
오늘
어제
  • 분류 전체보기
    • 기술 경험
    • 기술에 대한 생각들
    • 회고록
    • 프로그라피
    • 구 게시글
      • 백엔드 찍먹
      • 삽질
      • React
      • 라이브러리 소개
      • Breaking 프로젝트

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • react
  • 아이디어 도출
  • JS로 React 구현하기
  • 프로그라피 8기
  • 노드버드
  • 프로그라피
  • 리엑트 노드버드
  • 프로그라피 React
  • typescript
  • 삽질
  • 프론트엔드
  • Modal
  • 전역상태
  • 서비스 발전 과정
  • Redux
  • 셀프다이닝
  • SVG
  • 상태관리
  • react-query
  • query string

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
두피만

FE 던지기

props로 modal관리는 이제 그만
구 게시글/React

props로 modal관리는 이제 그만

2022. 5. 17. 14:53

페이지로 만들기는 싫고 간단한 창을 띄워 한 페이지 내에서 유저의 접근을 받고 싶을 때 modal을 애용해 왔다 새 페이지를 왔다 갔다 하는 것보다 좀 더 한 템포 빠르게 유저와의 상호작용이 일어나 좋아했다.

 

Modal 동작원리

modal을 동작하게 하는 방법에는 크게 2가지가 있다

  1. modal open close시에 dom에 직접 component를 넣다 빼는 방법
  2. css의 visible을 이용해서 modal이 안보이는 것처럼 보이게 하는 방법

1번의 방법은 open close마다 component를 랜더링 한다는 의미는 modal전체를 다시 그려야 한다는 것이므로 modal이 커질수록 open close시에 반응이 늦어진다는 이야기이다. 그래서 대부분의 modal창에서는 2번 방법을 사용한다.

 

 

 

 

Modal의 상태 관리

react에서는 이 modal을 state로 관리한다. 다만 이 modal을 관리하다 보니 고민하나 가 생겼다

//antd 공식문서 예제

import React, { useState } from 'react';
import { Modal, Button } from 'antd';

const App = () => {
  const [isModalVisible, setIsModalVisible] = useState(false);

  const showModal = () => {
    setIsModalVisible(true);
  };

  const handleOk = () => {
    setIsModalVisible(false);
  };

  const handleCancel = () => {
    setIsModalVisible(false);
  };

  return (
    <>
      <Button type="primary" onClick={showModal}>
        Open Modal
      </Button>
      <Modal title="Basic Modal" visible={isModalVisible} onOk={handleOk} onCancel={handleCancel}>
        <p>Some contents...</p>
        <p>Some contents...</p>
        <p>Some contents...</p>
      </Modal>
    </>
  );
};

ReactDOM.render(<App />, mountNode);

위의 antd 예제처럼 modal을 관리하는 버튼이 있고 밑에 modal component를 넣게 되는데 이 버튼을 클릭 시에 modal창이 열리게 된다.

 

react는 기본적으로 state가 바뀌게 되면은 컴포넌트가 리 랜더링 되게 된다. modal도 state로 관리를 하기 때문에 open이나 close할때 이 state가 바뀌게 될 것이고 이에따라 해당되는 컴포넌트가 리랜더링 되게 된다. 

 

프로젝트를 하다 보면 버튼이 있는 컴포넌트의 level에서 다양한 tag들이 추가되게 되는데 modal을 관리하는 state가 바뀔 때마다 이들이 전부 리 랜더링이 된다. 또한 하위 페이지에서 modal창을 호출하고 싶으면 props로 하위 페이지까지 넘겨주어야 한다. 이는 컴포넌트의 의존성을 높이게 되는 악영향을 준다.

 

 

 

props시에 문제 상황1

트위터 페이지를 보자

트위터 페이지
로그인시에 나오는 modal창
bts 게시글에 답글을 남기려 하였을때
이때 나오는 로그인 modal창

위의 두 개 modal component는 같은 component이다 하지만 위의 props 방법으로 호출하게 되면 메인 페이지와 트윗 댓글 쓰는 페이지에 modal과 state를 두 번 정의해야할것이고 이는 같은 컴포넌트가 두번 랜더링이 되게 되면서 재사용성이 떨어지게 된다.

 

props시에 문제 상황2

내가 프로젝트에서 경험했던 것이다. modal의 parent component에 mount시에 get요청이 호출되도록 설계를 하였다. modal창을 추가하니 modal 창을 열을 때나 닫을 때 이 parent component가 리 랜더링이 발생하며 get요청이 계속 발생하는 상황에 놓인 것이다. 

 

 

 

해결방안

modal의 state를 전역 상태로 바꾸는 것이다 나는 redux를 사용하고 있어서 redux에 새로운 slice를 만든후에 modal을 제어하였다 이렇게 하면 modal이 필요한 어떤 곳에서도 dispatch를 이용해 원하는 modal을 띄울수 있었고 parent component의 rerendering은 일어나질 않는다 

//component
<Button type="info" onClick={() => dispatch(openPreviewModal())}>
//클릭시 modal이 열림
//reducer

openPreviewModal: (
      state,
    ) => {
      state.previewModal = true;
    },
    closePreviewModal: (
      state,
    ) => {
      state.previewModal = false;
    },

- 전역상태로 사용하면 modal을 딱 한 번만 정의하고 모든 페이지 및 컴포넌트에서 이 modal을 사용을 할 수 있다

- 이는 modal과 관련된 리 랜더링을 신경쓰지 않아도 된다.

- modal과 이를 사용하는 컴포넌트간의 의존성이 사라지게 된다.

 

 

 

 

참고하면 좋은 글

https://www.notion.so/modal-007c2074252b4a4b8ddbe1b1f541f540#5c94fed7f0d5468095100ad42a7cbc71

https://nakta.dev/how-to-manage-modals-1

 

낙타의 블로그 :: 효율적인 modal 관리 with React(1)

중앙화된 모달 관리

nakta.dev

 

'구 게시글 > React' 카테고리의 다른 글

JS 프로젝트 TS로 마이그레이션하기  (0) 2022.11.25
CSR SSR SSG(NEXT JS) SPA MPA 정리  (0) 2022.06.19
React 상태관리와 불변성  (0) 2022.05.29
SVG 태그  (0) 2022.05.22
    '구 게시글/React' 카테고리의 다른 글
    • JS 프로젝트 TS로 마이그레이션하기
    • CSR SSR SSG(NEXT JS) SPA MPA 정리
    • React 상태관리와 불변성
    • SVG 태그
    두피만
    두피만

    티스토리툴바