본문 바로가기
취미 공부/Daily

2024. 06. 06 (목) 6주차 - Daily Coding - Day04

by Breadbread2 2024. 6. 6.
반응형

 

32강

리스트 렌더링 Part 1.

- 리스트를 state 값과 연동하기

  1. 추가

	const getPaymentFormData = (data) => {
		console.log('data', data)
		console.log('expenses', expenses)
			setExpenses([
					{
					id: Math.random().toString(),
					title: data.name,
					amount: data.price,
					date: new Date(data.today)
				},
				...expenses
			]
		);
	};

 

  2. 삭제

 

 

Math.random()

0보다 크거나 같고 1보다는 작은 숫자를 추출하는 기능.

 

삭제 기능

1. filter (id 값을 받을 때 유리)

const newFilteredArray = expenses.filter(item => item.id !== id);
		setExpenses(newFilteredArray);

 

2. slice (index 값을 받을 때 유리)

const beforeArray = expenses.slice(0, index);
		const afterArray = expenses.slice(index+1);
		setExpenses([...beforeArray, ...afterArray]);

 

33강

리스트의 KEY

- 리액트에서 리스트 형태로 만드는 모든 컴포넌트(HTML tag, 커스텀 컴포넌트 등)에 대해서 KEY 값을 고유하게 부여해 주어야  에러가 발생하지 않는다.

 

- 동일한 컴포넌트 (ex) map 을 사용할 때)가 지속적으로 리랜더링이 되면서 에러가 발생한다.

- 리액트 컴포넌트(또는 HTML tag)를 재사용해서 map 등의 함수로 여러 개를  만들 때 각각을 구분해주는 unique key 값이 필요하다

const Expenses = (props) => {
  return (
    <Card className="expenses">
      {props.items.map((item, index) => (
        <ExpenseItem
          key={item.id}
          id={item.id}
          index={index}
          title={item.title}
          amount={item.amount}
          date={item.date}
          deleteExpenseItem = {props.deleteExpenseItem}
        />
      ))}
    </Card>
  );
}

 

 


Q. 오늘의 문제

해당 Form 부분에 Form Input 타입 중 지금까지 쓰지 않은 타입을 3개 이상 사용해서 Form Data를 받아 리스트로 전달해보기

ex. Radio, Checkbox, Color

 

 

 

나의 답안

// App.js

import { useState } from "react";
import "./App.css";
import PaymentForm from "./components/PaymentForm/PaymentForm";
import Expenses from "./components/Payments/Expenses";

function App() {
	const [expenses, setExpenses] = useState([
		{
			id: "e1",
			title: "수건",
			amount: 12.33,
			date: new Date(2022, 3, 14),
			color: "#22830f",
			email: "aaa@zaa.fdddd",
			week: "2024, 1번째 주",
		}
	]);

	const getPaymentFormData = (data) => {
		console.log(data)
		setExpenses([
			{
				id: Math.random().toString(),
				title: data.name,
				amount: data.price,
				date: new Date(data.today),
				color: data.color,
				email: data.email,
				week: data.week,
			},
			...expenses
		],
		);
	};

	return (
		<>
			<PaymentForm getPaymentFormData={getPaymentFormData} />
			<Expenses items={expenses} />
		</>
	);
}

export default App;







// Expenses.js
import React, {useState} from 'react';

import ExpenseItem from "./ExpenseItem";
import Card from "../UI/Card";
import "./Expenses.css";
import ExpensesFilter from './ExpensesFilter';

const Expenses = (props) => {
	const [filteredYear, setFilteredYear] = useState('2023');

	const filterChangeHandler = (selectedYear) => {
		setFilteredYear(selectedYear);
	};

	const filteredExpenses = props.items.filter((expense) => {
		return expense.date.getFullYear().toString() === filteredYear;
	});
	

	return (
		<Card className="expenses">
			<ExpensesFilter
				selected={filteredYear}
				onChangeFilter={filterChangeHandler}
			/>
			{filteredExpenses.length > 0 ?
				filteredExpenses.map((item) => (				
					<ExpenseItem
						title={item.title}
						amount={item.amount}
						date={item.date}
						color={item.color}
						email={item.email}
						week={item.week}
					/>
			)) : <p>값이 없습니다.</p>}
		</Card>
	);
};

export default Expenses;



// ExpenseItem.js
import React from "react";

import ExpenseDate from "./ExpenseDate";
import Card from "../UI/Card";
import "./ExpenseItem.css";

const ExpenseItem = (props) => {
	return (
		<Card className="expense-item">
			<div className="expense-item__description">
				<ExpenseDate date={props.date} />
				<h2>{props.title}</h2>
				<div className="expense-item__color">{props.color}</div>
				<div className="expense-item__color">{props.email}</div>
				<div className="expense-item__color">{props.week}</div>
				<div className="expense-item__price">${props.amount}</div>
			</div>
		</Card>
	);
};

export default ExpenseItem;






// PaymentForm.js
import React, { useState } from "react";

import "./PaymentForm.css";

const PaymentForm = ({ getPaymentFormData }) => {
	const [objectState, setObjectState] = useState({
		name: '',
		price: 0,
		today: new Date(),
		email: '',
		color: '',
		week: '',
	});

	const inputTypeTextChangeHandler = (event) => {
		setObjectState(prevState => ({ ...prevState, name: event.target.value }))
	}
	const inputTypeNumberChangeHandler = (event) => {
		setObjectState(prevState => ({ ...prevState, price: event.target.value }))
	}
	const inputtypeDateChangerHandler = (event) => {
		setObjectState(prevState => ({ ...prevState, today: event.target.value }))
	}
	const inputTypeEmailChangeHandler = (event) => {
		setObjectState(prevState => ({ ...prevState, email: event.target.value }))
	}
	const inputTypeColorChangeHandler = (event) => {
		setObjectState(prevState => ({ ...prevState, color: event.target.value }))
	}
	const inputTypeWeekChangeHandler = (event) => {
		setObjectState(prevState => ({ ...prevState, week: event.target.value }))
	}

	const buttonSubmitHandler = (event) => {
		event.preventDefault();

		getPaymentFormData(objectState);
		// console.log(objectState);

		setObjectState({
			name: '',
			price: 0,
			today: new Date(),
			email: '',
			color: '',
			week: '',
		});
	};

	return (
		<div className="new-payment">
			<form onSubmit={buttonSubmitHandler}>
				<div className='new-payment__controls'>
					<div className='new-payment__control'>
						<label>이름</label>
						<input type='text' value={objectState.name} onChange={inputTypeTextChangeHandler} />
					</div>

					<div className='new-payment__control'>
						<label>금액</label>
						<input type='number' min='0.01' step='0.01' value={objectState.price} onChange={inputTypeNumberChangeHandler} />
					</div>

					<div className='new-payment__control'>
						<label>날짜</label>
						<input type='date' min='2023-01-01' max='2024-12-31' value={objectState.today} onChange={inputtypeDateChangerHandler} />
					</div>

					<div className='new-payment__control'>
						<label>이메일</label>
						<input type='email' value={objectState.email} onChange={inputTypeEmailChangeHandler} />
					</div>

					<div className='new-payment__control'>
						<label>색깔</label>
						<input type="color" value={objectState.color} onChange={inputTypeColorChangeHandler} />
					</div>

					<div className='new-payment__control'>
						<label>주</label>
						<input type="week" value={objectState.week} onChange={inputTypeWeekChangeHandler} />
					</div>
				</div>

				<div className='new-payment__actions'>
					<button type='submit' onClick={buttonSubmitHandler}>결제 추가</button>
				</div>
			</form>
		</div>
	);
};

export default PaymentForm;
반응형