React 모달에서 입력값을 "수정하기" 버튼을 눌러야 반영되도록 하기

2025. 2. 17. 00:02프론트엔드/REACT

728x90

🚀 React 모달에서 입력값을 "수정하기" 버튼을 눌러야 반영되도록 하기

문제 상황

React에서 연락처를 수정하는 모달을 만들 때, 입력할 때마다 user 상태가 즉시 변경되면 실제 데이터가 바로 덮어씌워져서 원하지 않는 문제가 발생할 수 있다.
우리는 입력 중에는 임시 상태에 저장하고, "수정하기" 버튼을 눌렀을 때만 실제로 변경되도록 하고 싶다.


📌 문제점

const [user, setUser] = useRecoilState(profileEditState);

const handleChange = (e) => {
  setUser((prevUser) => ({
    ...prevUser,
    contact_id: e.target.value, // ❌ 입력할 때마다 user 상태가 즉시 변경됨
  }));
};

🔥 이 코드의 문제점

  • 입력할 때마다 user가 즉시 업데이트되어 실제 데이터가 변경됨
  • "수정하기" 버튼을 누르지 않아도 변경 내용이 반영됨 모달창에서느 수정하기를 눌렀을때만 적용하고 싶음
    기존의 컴포너트를 이용하고 싶음

🎯 해결 방법

입력할 때는 tempUser 상태를 변경하고, 버튼을 눌렀을 때만 user를 업데이트한다.
모달을 닫았다가 다시 열면 기존 데이터(user)가 유지되도록 한다.


변경된 코드

import React, { useState, useEffect } from "react";
import { useRecoilState } from "recoil";
import { profileEditState } from "../Atoms";
import "../css/components/ContactEditModal.css";
import ContactMethod from "./ContactMethod"; // ✅ ContactMethod 컴포넌트 추가

const ContactEditModal = ({ isOpen, onClose }) => {
  const [user, setUser] = useRecoilState(profileEditState);
  const [tempUser, setTempUser] = useState(user); // ✅ 입력값을 임시 저장하는 상태
  const [isContactVerified, setIsContactVerified] = useState(false); // 인증 여부 상태

  // 모달이 열릴 때 기존 연락처 정보 불러오기 (초기값 동기화)
  useEffect(() => {
    setTempUser(user);
  }, [isOpen, user]);

  // 연락처 입력 변경 핸들러 (임시 상태 업데이트)
  const handleChange = (e) => {
    if (isContactVerified) {  
      setTempUser((prev) => ({
        ...prev,
        contact_id: e.target.value,
      }));
    }
  };

  // 수정 버튼 클릭 시 Recoil 상태 업데이트 (최종 반영)
  const handleSave = () => {
    if (isContactVerified) {
      setUser(tempUser); // ✅ 임시 상태를 실제 상태로 반영
      onClose(); // 모달 닫기
    }
  };

  if (!isOpen) return null;

  return (
    <div className="contact-modal-overlay">
      <div className="contact-modal-container">
        <h2 className="contact-modal-title">연락처 수정</h2>
        <p className="contact-modal-text">새로운 연락처를 입력해주세요.</p>

        <button className="contact-modal-close-button" onClick={onClose}>
          닫기
        </button>

        {/* ✅ ContactMethod 컴포넌트 사용 (임시 상태 tempUser를 전달) */}
        <ContactMethod
          user={tempUser} // ✅ 입력 중에는 tempUser 사용
          handleChange={handleChange}
          setIsContactVerified={setIsContactVerified}
          setUser={setTempUser} // ✅ 임시 상태 업데이트
        />

        <button
          className={`contact-save-button ${isContactVerified ? "active" : "inactive"}`}
          onClick={handleSave}
          disabled={!isContactVerified}
        >
          수정하기
        </button>
      </div>
    </div>
  );
};

export default ContactEditModal;

💡 변경된 코드의 핵심

1️⃣ tempUser를 새로 추가 (임시 저장용)

  • user를 바로 변경하지 않고, 입력할 때는 tempUser에만 저장한다.
  • "수정하기" 버튼을 눌렀을 때 user를 업데이트한다.

2️⃣ useEffect를 활용한 초기화

useEffect(() => {
  setTempUser(user);
}, [isOpen, user]);
  • 모달이 열릴 때마다 tempUser를 user와 동일하게 설정하여 기존 데이터를 유지한다.

3️⃣ 입력값을 tempUser에 저장

const handleChange = (e) => {
  if (isContactVerified) {  
    setTempUser((prev) => ({
      ...prev,
      contact_id: e.target.value,
    }));
  }
};
  • user가 아닌 tempUser를 변경하여, 입력할 때 user가 즉시 바뀌는 걸 방지한다.

4️⃣ 버튼을 눌러야만 user 업데이트

const handleSave = () => {
  if (isContactVerified) {
    setUser(tempUser); // ✅ 최종적으로 user를 업데이트
    onClose(); // 모달 닫기
  }
};
  • "수정하기" 버튼을 눌러야 user 상태가 바뀌도록 한다.

 

728x90