24. 05. 28 TIL (props-drilling-2)
4. InputForm 파일
import React, { useState } from 'react';
import { v4 as uuidv4 } from 'uuid';
밑의 uuid는 id를 생성해주는 라이브러리다.
설치 후 저렇게 넣어준다.
이제 어떻게 하지...........
라고 하지 말고 먼저 생각을 해본다.
일단 상단 인풋 값을 입력하는 디자인을 먼저 짜보자.
그럼 폼 태그 내부에 각 항목을 넣어서 디자인 해본다.
4번으로 이동.
1.
const InputForm = ({ setItemList, MonthSaveFunc }) => {
const [dateValue, setDateValue] = useState('');
const [itemValue, setItemValue] = useState('');
const [amountValue, setAmountValue] = useState('');
const [descriptionValue, setDescriptionValue] = useState('');
자... 이제 useState를 만들어주는데, 각각 인풋창에 맞게 4개 만들어 준다.
초기값은 빈 값이다. 이제 onChange에 들어가는 함수를 입력해주자.
그리고 setItemList와 MonthSaveFunc를 받아오는 걸 기억하자.
2번으로 이동.
2.
const inputDatefunc = (e) => {
setDateValue(e.target.value);
};
const inputItemfunc = (e) => {
setItemValue(e.target.value);
};
const inputAmountfunc = (e) => {
setAmountValue(e.target.value);
};
const inputDescriptionfunc = (e) => {
setDescriptionValue(e.target.value);
};
자 이제 각 인풋 창에서 함수를 실행해서 변경된 값을 set~에 넣어주는 것이다.
그럼 dateValue의 값들이 업데이트 될 듯.
이제 submit 함수를 만들어 본다. 3번으로 이동.
3.
const submitForm = (e) => {
e.preventDefault();
const newItem = {
date: dateValue,
item: itemValue,
amount: amountValue,
description: descriptionValue,
id: uuidv4(),
};
const date = parseInt(newItem.date.slice(6, 7));
MonthSaveFunc(date);
if (dateValue && itemValue && amountValue && descriptionValue !== '') {
setItemList((prev) => [...prev, newItem]);
setDateValue('');
setItemValue('');
setAmountValue('');
setDescriptionValue('');
} else {
alert('값을 모두 입력해주세요');
}
};
onSubmit을 할 때 실행되는 함수를 만드는 것이다.
이 함수의 역할은 값을 모아서 리스트로 출력해준다.
일단 폼은 새로고침 되므로 e.preventDefault로 일단 막자.
그리고 이걸 보여줘야 할 것이 아닌가?
리스트에 추가하기 위해 객체로 만든다.
이 객체엔 value에 있던 업데이트된 현재 인풋값을 넣어준다.
또 id는 각 항목을 고유하게 식별하기 위해서 uuid를 사용해 넣어준다.
일단 newItem 객체에서 달을 뽑아 MonthSaveFunc 함수에 전달한다.
이건 사용자가 입력한 date에서 달을 뽑아 전달하고, 그 달을 화면에 표시하도록 하는 목적인 걸로 기억한다.
이제 각 dateValue 등 현재 업데이트 된 값이 비어있나 확인한다. 하나라도 비어있으면 조건문이 실행되지 않는다.
비어있지 않으면 setItemList에서 매개변수로 prev(이전 항목?)을 받아오고,
스프레드 연산자로 prev를 복사한 뒤 newItem을 붙인다.
그럼 불변성을 유지하면서 상태를 업데이트 한다.
그리고 값이 비어있다면 alert를 띄운다.
4.
return (
<>
<form onSubmit={submitForm}>
<div>
<label htmlFor="date">날짜</label>
<input type="date" id="date" onChange={inputDatefunc} value={dateValue} />
</div>
<div>
<label htmlFor="item">항목</label>
<input type="text" id="item" placeholder="지출 항목" onChange={inputItemfunc} value={itemValue} />
</div>
<div>
<label htmlFor="amount">금액</label>
<input type="number" id="amount" placeholder="지출 금액" onChange={inputAmountfunc} value={amountValue} />
</div>
<div>
<label htmlFor="description">내용</label>
<input type="text" id="description" placeholder="지출 내용" onChange={inputDescriptionfunc} value={descriptionValue} />
</div>
<button type="submit">저장</button>
</form>
</>
);
};
label 태그는 저 항목이라는 글씨를 보여준다.
htmlFor=date는 input의 id와 연결해준다.
그래서 라벨 태그를 클릭해도 인풋창에 커서가 가게 된다.
이걸 각각 작성해서 폼태그 내부에 넣는데,
폼 태그는 이 여러 입력 요소를 모아서 제출할 수 있게 해준다.
그리고 버튼의 type submit은 폼의 데이터가 서버로 제출될 수 있도록 한다.
onSubmit은 폼이 제출될 때 실행할 함수를 정한다.
즉, 인풋값을 입력 후 폼을 제출하면 onSubmit의 함수가 실행된다.
일단 입력값을 어떻게 가져오는지부터 알아보자.
일단 각각 인풋에 onChange와 value를 입력해 줘야 한다.
onChange는 값이 입력, 지워질 때마다 실행되는 이벤트다.
value는 말 그대로 인풋창에 어떤 값이 들어있는지 정해준다.
내가 1을 value에 입력하면 value는 1로 고정된다.
value에 dataValue를 넣어주면 인풋창의 값이 항상 dateValue와 일치하게 된다.
이제 1번으로 이동.
5. MonthBtn 파일
이 파일은 달 버튼을 만드는 파일이다.
먼저 달을 만드려면 배열을 만들어주자.
const months = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
잔
그리고 일단 2번으로 간다.
const MonthBtn = ({ MonthSaveFunc }) => {
MonthSaveFunc 함수를 받아오는데 이 함수는 라우터에 있는 함수다.
올리기 귀찮으니까
const MonthSaveFunc = (month) => {
setSaveMonth(month);
localStorage.setItem('month', month);
};
이렇게 생겼다. 일단 더 봐보자.
자 보면 MonthSaveFunc 함수가 실행되어 month를 받아와 setSaveMonth에 주고 있다.
(이 setSaveMonth는 라우터에 작성되었다.)
로컬 스토리지는 이 클릭한 달을 받아서 저장한다. 이 저장한 것은 마지막에 클릭한 달을 저장하는 건데
다시 가져와서
const [saveMonth, setSaveMonth] = useState(lastMonth);
여기 넣어주면 초기값으로 마지막으로 클릭한 달을 가져온다.
2.
{months.map((month, index) => {
return (
<Button
key={index}
onClick={() => {
MonthSaveFunc(month);
}}
>
{month}월
</Button>
);
})}
먼저 배열에 있는 숫자를 꺼내려면 map을 돌려야 한다.
months 배열에서 요소 하나하나인 month를 키로 index를 주어 돌린다.
그리고 돌리면서 달 버튼을 뱉어낸다.
그리고 이 버튼을 클릭하면? MonthSaveFunc 함수에 month가 전달되어 실행된다.
다시 위로 가볼까...