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에 전달해야 함
    setUserInput(prevUserInput => ({  // 순서가 보장되어 있지 않는 비동기 특징으로 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,
      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;

반드시 setter를 통해 상태값을 업데이트 해줘야 한다 !


import React, { useState } from 'react';
import './CheckBoxStyle.css'; 

// 체크박스, 라디오박스 등 기본 디자인이 별로이니 이렇게 숨겨놓고 스타일 처리할 수 있다 !
function CheckBoxStyle() {

    // 체크상태를 관리
    const [isChecked, setIsChecked] = useState(false);

    // 업데이트된 체크상태를 반대로 !
    const checkChangeHandler = e => {
        setIsChecked(!isChecked);
    }

  return (
    <div className="checkbox-container">
      **<input**
        type="checkbox"
        id="styled-checkbox"
        **checked={isChecked}
        onChange={checkChangeHandler}**
      />
      **<label**
        htmlFor="styled-checkbox"
        **className={isChecked ? 'checked' : 'unchecked'}**
      >
        Check me!
      </label>
    </div>
  );
}

export default CheckBoxStyle;
.checkbox-container {
    display: flex;
    align-items: center;
    margin: 20px;
  }
  
  input[type="checkbox"] {
    display: none;
  }
  
  label {
    cursor: pointer;
    padding: 10px 20px;
    border: 2px solid #ccc;
    border-radius: 5px;
    transition: background-color 0.3s, border-color 0.3s;
  }
  
  **label.unchecked {
    background-color: white;
    border-color: #ccc;
  }
  
  label.checked {
    background-color: #4caf50;
    border-color: #4caf50;
    color: white;
  }**