개인 프로젝트의 묘미는 기능과 코드를 내 마음대로 할 수 있다는 것!
인턴십 전까지 남아 있는 시간동안 개인 프로젝트를 할 수 있는 시간이 있어서 다행이다.
역시 사람이 여유가 조금 생기니, 만들어 보고 싶었던 기능, 시도해보고 싶은 것들이 떠오르네.. 참 신기해..
중복 파일, 코드를 최대한 줄여보고 싶은 마음에,
[수입], [지출] 버튼을 눌렀을 때 나오는 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에 $ 기호를 붙이니 에러는 싹 사라지고, 콘솔창을 깔끔하게 유지한 채, 원하는 결과물을 얻을 수 있었다.
수입 버튼 클릭 시
지출 버튼 클릭 시