단일 Modal 컴포넌트 props 사용해서 수입/지출 내역 관리하기 [Warning: React does not recognize the modalColor prop on a DOM element.]

2024. 8. 17. 20:04·Programming/React

개인 프로젝트의 묘미는 기능과 코드를 내 마음대로 할 수 있다는 것!

 

인턴십 전까지 남아 있는 시간동안 개인 프로젝트를 할 수 있는 시간이 있어서 다행이다.

역시 사람이 여유가 조금 생기니, 만들어 보고 싶었던 기능, 시도해보고 싶은 것들이 떠오르네.. 참 신기해..

 

중복 파일, 코드를 최대한 줄여보고 싶은 마음에,

[수입], [지출] 버튼을 눌렀을 때 나오는 RegistModal을 하나의 파일에서 적용 해보기로 하였다.

 

수입 모달과 지출 모달의 차이점

1) 제목

2) 색상

3) input placeholder

4) [등록하기] 버튼 클릭 시, props 전달

 

내가 적용한 방법은 아래와 같다.

 

1. 지출을 기준으로 상태를 초기화한다.

  const [modalColor, setModalColor] = useState("#EB0130"); // 지출 기준
  const [modalTitle, setModalTitle] = useState("지출"); // 지출 기준
  const [isSpendBttClicked, setIsSpendBttClicked] = useState(false); // 지출 기준

2. 버튼을 눌렀을 때 props를 전달해서 상태를 변경시켜주는 함수를 작성한다.

  const clickShowModal = (
    color: string,
    title: string,
    spendClicked: boolean
  ) => {
    setModalColor(color);
    setModalTitle(title);
    setIsSpendBttClicked(spendClicked);
    setShowModal(true);
  };

3. 수입과 지출에 어떤 값을 전달할 건지 작성해준다. (RegistModal 전달하는 props가 많은데, 이것도 정리해야할 듯)

<div className="button-container">
              <m.AddButton
                $bgColor="#431EF5"
                onClick={() => clickShowModal("#431ef5", "수입", false)}
              >
                수입+
              </m.AddButton>
              <m.AddButton
                $bgColor="#EB0130"
                onClick={() => clickShowModal("#EB0130", "지출", true)}
              >
                지출+
              </m.AddButton>
              <RegistModal
                show={showModal}
                onClose={clickCloseModal}
                isSpendBttClicked={isSpendBttClicked}
                onAddIncome={handleAddIncome}
                onAddSpend={handleAddSpend}
                modalColor={modalColor}
                modalTitle={modalTitle}
              />
            </div>

4. 지출버튼이 눌린 것을 기준으로 제목/색상/placeholder return 값을 보여준다.

return (
    <m.ModalContainer>
      <m.ModalContent $modalColor={modalColor}>
        <div>
          <button onClick={handleCloseModal}>X</button>
          <h1>{modalTitle} 내역 작성하기</h1>
          <div className="form-grid">
            <label>날짜</label>
            <h2>
              {!isSpendBttClicked ? (
                <>
                  <SmallDateSelector
                    modalColor={modalColor}
                    selectedDate={setIncomeDate}
                  />
                </>
              ) : (
                <>
                  <SmallDateSelector
                    modalColor={modalColor}
                    selectedDate={setSpendDate}
                  />
                </>
              )}
            </h2>
          </div>
          <div className="form-grid">
            <label>내용</label>
            <h2>
              {!isSpendBttClicked ? (
                <>
                  <input
                    value={incomeContent}
                    maxLength={30}
                    onChange={(e) => setIncomeContent(e.target.value)}
                    placeholder="수입 내용 30자 이하로 작성해주세요!"
                  />
                </>
              ) : (
                <>
                  <input
                    value={spendContent}
                    maxLength={30}
                    onChange={(e) => setSpendContent(e.target.value)}
                    placeholder="지출 내용 30자 이하로 작성해주세요!"
                  />
                </>
              )}
            </h2>
          </div>
          <div className="form-grid">
            <label>금액</label>
            <h2>
              {!isSpendBttClicked ? (
                <>
                  <input
                    value={incomeAmount ?? ""}
                    maxLength={9}
                    onChange={handleIncomeAmountChange}
                    placeholder="수입 금액을 입력해주세요!"
                    type="number"
                  />
                </>
              ) : (
                <>
                  <input
                    value={spendAmount ?? ""}
                    maxLength={9}
                    onChange={handleSpendAmountChange}
                    placeholder="지출 금액을 입력해주세요!"
                    type="number"
                  />
                </>
              )}
            </h2>
          </div>
        </div>
        <m.RegistButton $modalColor={modalColor} onClick={handleSubmit}>
          등록하기
        </m.RegistButton>
      </m.ModalContent>
    </m.ModalContainer>
  );

5. [등록하기] 버튼 클릭 시, 데이터 전달하는 props 구분하기

const handleSubmit = () => {
    if (!isSpendBttClicked) {
      if (incomeDate && incomeContent && incomeAmount !== null) {
        onAddIncome({
          date: incomeDate,
          content: incomeContent,
          amount: incomeAmount,
        });
        setIncomeContent("");
        setIncomeAmount(null);
        setIncomeDate("");
      }
    } else {
      if (spendDate && spendContent && spendAmount !== null) {
        onAddSpend({
          date: spendDate,
          content: spendContent,
          amount: spendAmount,
        });
        setSpendContent("");
        setSpendAmount(null);
        setSpendDate("");
      }
    }
  };

+이 부분은 db와 다른 코드와 체이닝되어 있는 부분이 많기 때문에 다른 편에서 다루어야지..


그렇다면 디자인에서  $modalColor  이 기호에 대해 의문이 들 수 있다.

 

순조롭게 코드를 작성하고 화면에서 버튼을 누르는 순간,

이런 에러가 콘솔에 자꾸 찍히는 것이었다. $ 해당 기호를 제외하고 props를 전달하고 있었다.

export const ModalContent = styled.div<{ $modalColor: string }>`
  position: relative;
  width: 30rem;
  height: 25rem;
  border: 1px solid ${(props) => props.$modalColor};
  border-radius: 1rem;
  box-shadow: 0 10px 12px rgba(0, 0, 0, 0.1);
  color: ${(props) => props.$modalColor};
  background-color: white;
  display: flex;
  flex-direction: column;
  align-items: center;
  z-index: 1000;

  & button {
    position: absolute;
    top: 0;
    right: 0;
    font-size: 1.1rem;
    margin-top: 5px;
    margin-right: 5px;
    cursor: pointer;
    border-radius: 1rem;
    border: none;
    background-color: white;
    color: ${(props) => props.$modalColor};
  }

 

해당 에러는 modalColor prop이 DOM 요소에 직접 전달되고 있다는 경고이다.

modalColor 는 스타일 컴포넌트에서 사용하기 위함이다.

직접 전달된 DOM 요소에서는 modalColor 을 인식하지 못하기에 이런 에러가 발생하는 것이다.

 

검색 결과를 통해 가장 간단한 방법은 prop 앞에 $를 붙이는 것이다.

 

$ 의미

- styled-component에 전달된다.

- 실제 HTML 요소로 전달되지 않는다.

- 해당 기호를 사용하면 브라우저가 이해하지 못하는 속성을 실수로 HTML 요소에 전달하지 않게 된다.

 

그렇게 관련 모든 props에 $ 기호를 붙이니 에러는 싹 사라지고, 콘솔창을 깔끔하게 유지한 채, 원하는 결과물을 얻을 수 있었다.

수입 버튼 클릭 시

 

지출 버튼 클릭 시

'Programming > React' 카테고리의 다른 글

AWS S3로 프론트엔드 배포하기  (0) 2024.09.07
다크모드 GlobalStyle 적용하기 : [Cannot read properties of undefined (reading 'body'), The above error occurred in the <l2> component]  (1) 2024.08.29
chart.js React에 적용하기  (0) 2024.08.21
Modal 생성 후 배경 Blur 처리 하기  (0) 2024.08.04
무한 루프 직면할 경우 : Too many re-renders. React limits the number of renders to prevent an infinite loop.  (0) 2024.04.07
'Programming/React' 카테고리의 다른 글
  • 다크모드 GlobalStyle 적용하기 : [Cannot read properties of undefined (reading 'body'), The above error occurred in the <l2> component]
  • chart.js React에 적용하기
  • Modal 생성 후 배경 Blur 처리 하기
  • 무한 루프 직면할 경우 : Too many re-renders. React limits the number of renders to prevent an infinite loop.
gitit
gitit
짬내서 쓰는 프론트엔드와 기술 메모 공간
  • gitit
    깃잇-gitit
    gitit
  • 전체
    오늘
    어제
    • 분류 전체보기
      • Coding Test
        • Programmers
        • BackJoon
      • Development Tools
        • Firebase
        • Git
        • Monorepo
      • Programming
        • JavaScript
        • React
        • React-Native
      • etc.
        • GeekNews
        • Blockchain
      • Technical Interview
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    BFS
    javascript
    코딩
    js
    Firebase
    프론트엔드
    매일메일
    기본문법
    파이어베이스
    개발
    코테
    자바스크립트
    S3
    styled-components
    리액트
    알고리즘
    긱뉴스
    프로그래머스
    백준
    기술 질문
    node.js
    코딩테스트
    geeknews
    파이썬
    React
    modal
    AWS
    독학
    frontend
    kakao
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.1
gitit
단일 Modal 컴포넌트 props 사용해서 수입/지출 내역 관리하기 [Warning: React does not recognize the modalColor prop on a DOM element.]
상단으로

티스토리툴바