ํํฅ์ ์ ๋ฌ - props๋ก ๋ฐ์ดํฐ ์ ๋ฌํ๋ ๋ฐฉ๋ฒ !
์ํฅ์ ์ ๋ฌ - ์ง๊ธ ExpenseForm์์ ์ถ๊ฐํ ๋ฐ์ดํฐ๋ฅผ App.js์ ์ฌ๋ ค์ ๋ถ์ฌ์ผ ํ๋ ์ํฉ


โญ์ํฅ์ ์ ๋ฌ props ์ฝ๋ ๋ฆฌ๋ทฐ
import React, { useState } from 'react';
import './ExpenseForm.css';
const ExpenseForm = ({ onAdd, onCancel }) => {
// ์
๋ ฅ์นธ์ ์๋ 3๊ฐ์ ๊ฐ์ ๊ฐ๊ฐ์ ์ํ๊ฐ์ผ๋ก ๊ด๋ฆฌ - ๋จ์ผ๊ฐ ์ํ
// const [title, setTitle] = useState('');
// const [price, setPrice] = useState(0);
// const [date, setDate] = useState(null);
// โโ ์
๋ ฅ์นธ์ ์๋ 3๊ฐ์ ๊ฐ์ ํ๋์ ์ํ๊ฐ์ผ๋ก ๊ด๋ฆฌ - ๊ฐ์ฒด ์ํ
// ์ด๊ธฐ๊ฐ์ ์
๋ฐ์ดํธํ ์ํ๋ฅผ ๊ฐ์ฒดํํ๋ก ๋ฃ์ด์ค๋ค !
const [userInput, setUserInput] = useState({
title: '',
price: '',
date: ''
});
// ์ค๋ ๋ ์ง๋ฅผ YYYY-MM-DD ํ์์ผ๋ก ๊ฐ์ ธ์ค๋ ํจ์
const getTodayDate = () => {
const today = new Date();
const year = today.getFullYear();
const month = String(today.getMonth() + 1).padStart(2, '0'); // ์์ 0๋ถํฐ ์์ํ๋ฏ๋ก 1์ ๋ํด์ค
const day = String(today.getDate()).padStart(2, '0');
return `${year}-${month}-${day}`;
}
// 1. ์ ๋ชฉ์ด ์
๋ ฅ๋์์ ๋ ๋ฐ์ํ๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ
const titleChangeHandler = e => {
// userInput.title = e.target.value; (X)
// ๐ฅ๐ฅ ๊ฐ์ฒด๋ ๋ฐฐ์ด์ํ๋ก ๊ด๋ฆฌ๋๋ useState ์ํ๊ฐ์
// ์ํ๋ณ๊ฒฝ์ ์๋ก์ด ๊ฐ์ฒด๋ ๋ฐฐ์ด์ setter์ ์ ๋ฌํด์ผ ํจ
// โ ๋น๋๊ธฐ๊ฐ ์์๊ฐ ๋ณด์ฅ๋์ด ์์ง ์์ ์
๋ฐ์ดํธ๋๊ธฐ ์ ๊ฐ์ ๊ฐ์ ธ์ฌ ์ ์๊ธฐ ๋๋ฌธ์
// prevUserInput์ ์
๋ฐ์ดํธ๋ ์ต์ ์ํ๋ฅผ ๊ฐ์ ธ์์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์๋ค !
setUserInput(prevUserInput => ({
...prevUserInput,
title: e.target.value
}));
};
// 2. ๊ฐ๊ฒฉ์ด ์
๋ ฅ๋์์ ๋ ๋ฐ์ํ๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ
const priceChangeHandler = e => {
setUserInput({
...userInput,
price: +e.target.value
});
};
// 3. ๋ ์ง๊ฐ ์
๋ ฅ๋์์ ๋ ๋ฐ์ํ๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ
const dateChangeHandler = e => {
setUserInput({
...userInput,
date: e.target.value
});
};
// ํผ ์ ์ก ์ด๋ฒคํธ ํธ๋ค๋ฌ
const submitHandler = e => {
e.preventDefault(); // ํผ ์ ์ก ๋ฐฉ์ง
// console.log('ํผ์ด ์ ์ก๋จ!');
// ์ง์ถ ๋ด์ญ ๊ฐ์ฒด๋ฅผ ์์ฑ - ๊ฐ์ฒด์ํ๋ก ๊ด๋ฆฌ์ ํ์ ์์ !
// const newExpense = {
// title,
// price,
// date
// };
console.log(userInput);
**// App.js์๊ฒ ๋ฐ์ ํจ์๋ฅผ ํธ์ถ - ํํฅ์์ผ๋ก ๋ฐ์ดํฐ ๋ด์ ๋ฐ๊ตฌ๋ ๋ด๋ ค๋ณด๋ธ ๊ฒ !
//โโ - ๋ด๋ ค๋ณด๋ธ onAdd() ๋ฐ๊ตฌ๋์ userInput ๋ฐ์ดํฐ๋ฅผ ๋ด๋๋ค ! -> ํด๋น ๋ฐ์ดํฐ๊ฐ ํ์ํ ์ํฅ App.js์ userInput ๋ฐ์ดํฐ ๋ณด๋ด์ฃผ๊ธฐ !
onAdd({
...userInput,
date: new Date(userInput.date)
});**
// form input ๋น์ฐ๊ธฐ - ๋ฑ๋ก ํ ๋น๋ฌธ์์ด๋ก ์
๋ ฅ์ฐฝ์ ๊ฐ ๋น์์ฃผ๊ธฐ
setUserInput({
title: '',
price: '',
date: ''
});
};
return (
<form onSubmit={submitHandler}>
<div className="new-expense__controls">
<div className="new-expense__control">
<label>Title</label>
<input
type="text"
onChange={titleChangeHandler}
value={userInput.title}
/>
</div>
<div className="new-expense__control">
<label>Price</label>
<input
type="number"
min="100"
step="100"
onChange={priceChangeHandler}
value={userInput.price}
/>
</div>
<div className="new-expense__control">
<label>Date</label>
<input
type="date"
min="2019-01-01"
max={getTodayDate()}
onChange={dateChangeHandler}
value={userInput.date}
/>
</div>
</div>
<div className="new-expense__actions">
<button type="button" onClick={onCancel}>Cancel</button>
<button type="submit">Add Expense</button>
</div>
</form>
);
};
export default ExpenseForm;
import "./App.css";
import React from "react";
import ExpenseList from "./components/Expenses/ExpenseList";
import Greet from "./components/Greet";
import Counter from "./components/practice/Counter";
import NewExpense from "./components/new-expense/NewExpense";
import CheckBoxStyle from "./components/practice/CheckBoxStyle";
const App = () => {
// ์๋ฒ์์ ์ง์ถํญ๋ชฉ JSON ๋ฐฐ์ด์ ์๋ต ๋ฐ์
const **expenses** = [
{
title: "์์์ฅ ๋ฑ๋ก",
price: 100000,
date: new Date(2024, 6 - 1, 3),
},
{ title: "๋ค์ด์", price: 8000, date: new Date(2024, 7 - 1, 14) },
{
title: "๊น๋ฐฅ",
price: 4900,
date: new Date(2024, 7 - 1, 25),
},
];
**// โโ ExpenseForm์๊ฒ ๋ด๋ ค๋ณด๋ผ ํจ์ -> ๋ด๋ ค๋ณด๋ธ ๋ฐ๊ตฌ๋์์ userInput ๋ฐ์ดํฐ ๋ด์์ด !
const onAddExpense = (userInput) => {
console.log('App.js๊ฐ ๋ด๋ ค๋ณด๋ธ ํจ์ ํธ์ถ');
console.log(userInput);
// ์์ expenses ๊ฐ์ฒด์ ์ถ๊ฐํ๊ธฐ ! push
expenses.push(userInput);
}**
return (
<>
<CheckBoxStyle />
**<NewExpense onSave={onAddExpense}/>**
<ExpenseList expenses={expenses} />
</>
);
};
export default App;