[React] form submit후, 리로드 방지 및 양방향 바인딩

summereuna🐥·2023년 3월 11일
0

React JS

목록 보기
28/69
import { useState } from "react";
import "./ExpenseForm.css";

const ExpenseForm = () => {
  const [enteredTitle, setEnteredTitle] = useState("");
  const [enteredAmount, setEnteredAmount] = useState("");
  const [enteredDate, setEnteredDate] = useState("");
  
  const titleChangeHandler = (e) => {
    setEnteredTitle(e.target.value);
    console.log("Title changed!");
  };

  const amountChangeHandler = (e) => {
    setEnteredAmount(e.target.value);
    console.log("Amount changed!");
  };

  const dateChangeHandler = (e) => {
    setEnteredDate(e.target.value);
    console.log("Date changed!");
  };

  const submitHandler = (e) => {
    //1. 페이지 리로드 방지
    e.preventDefault();

    //2. state 결합하기: 제출된 폼의 내용을 모두 담은 객체 생성
    const expenseData = {
      title: enteredTitle,
      amount: enteredAmount,
      //날짜 생성자로 날짜 생성 후, 해당 날짜 문자열 분석하여 날짜 객체로 변환한 enteredDate 전달
      date: new Date(enteredDate),
    };

    //3. 양방형 바인딩: 입력 후 form에 적은 값 화면에서 없애기
    setEnteredTitle("");
    setEnteredAmount("");
    setEnteredDate("");
  };
  
  return (
    <form onSubmit={submitHandler}>
      <div className="new-expense__controls">
        <div className="new-expense__controls">
          <label htmlFor="new-expense-name">물품</label>
          <input
            type="text"
            onChange={titleChangeHandler}
            value={enteredTitle}
          />
        </div>
        <div className="new-expense__controls">
          <label htmlFor="new-expense-amount">금액</label>
          <input
            type="number"
            min="0.01"
            step="0.01"
            onChange={amountChangeHandler}
            value={enteredAmount}
          />
        </div>
        <div className="new-expense__controls">
          <label htmlFor="new-expense-date">날짜</label>
          <input
            type="date"
            min="2019-01-01"
            max="2023-12-31"
            onChange={dateChangeHandler}
            value={enteredDate}
          />
        </div>
      </div>
      <div className="new-expense__actions">
        <button type="submit">추가하기</button>
      </div>
    </form>
  );
};

export default ExpenseForm;

1. 페이지 리로드 방지 event.preventDefault();


브라우저는 form이 제출될 때 마다 웹페이지를 호스팅하고 있는 서버에 요청을 보내기 때문에 페이지를 리로드한다. JS로 수동으로 데이터를 수집하여 결합하는 방법으로 폼을 제출하고 싶다면 이러한 기본 동작을 비활성화 하면 된다.

event.preventDefault();로 기본요청이 보내지는 것을 막을 수 있다.
서버로 어떤 요청도 보내지 않기 때문에 페이지가 리로드되지 않는다. 계속해서 JS로 핸들링할 수 있다.

2. 각각 생성한 state 결합하기: 제출된 폼의 내용을 모두 담은 객체(Object) 생성


현재 state를 각각 생성했기 때문에 하나의 오브젝트로 담아야 한다.
form으로 받은 entered states를 아래의 코드 처럼 객체에 담아주면 된다.

const expenseData = {
  title: enteredTitle,
  amount: enteredAmount,
  date: new Date(enteredDate),
};

3. 양방형 바인딩: submit 후, form에 입력한 값 화면에서 없애기


submit 후, form에 적힌 값을 화면에서 사라지게 하려면 어떻게 해야할까?

바닐라 JS에서는 엘리먼트를 하나씩 가져와서 value의 내용을 지워주는 방식으로 진행했었다. 리액트에서는 state의 양방향 바인딩을 활용하여 그 기능을 구현할 수 있다.

  • state를 사용해 양방향 바인딩으로 input의 값을 입력하거나 재설정할 수 있다.
    1. 변경되는 input값 수신
    2. input에 새로운 값 다시 전달 가능

방법

  1. input 태그에 value 값으로 state인 enteredTitle를 바인딩한다.
<input
  type="text"
  onChange={titleChangeHandler}
  value={enteredTitle}
  />
  1. submitHandler에서 입력된 값을 객체에 넣어 준 후, setState("");로 각각의 state를 빈문자열로 재설정한다.
const submitHandler = (e) => {
  e.preventDefault();
  const expenseData = {
    title: enteredTitle,
    amount: enteredAmount,
    date: new Date(enteredDate),
  };
  
  setEnteredTitle("");
  setEnteredAmount("");
  setEnteredDate("");
};
  1. 그러면 form에 입력된 글자가 화면에서 사라진다.
profile
Always have hope🍀 & constant passion🔥

0개의 댓글