TIL: react에서 여러 가지 input 값을 관리하기

Perfume·2020년 12월 1일
0
post-custom-banner

react로 사내 인트라넷의 정보수정 페이지를 만들고 있다. 그런데..

이처럼 input창이 워낙 많아서 이 input의 값들을 어떻게 관리할지가 가장 큰 고민이었다. 일단 처음엔 컴포넌트를 하나 만든 다음에 map을 이용해 여러 개 뿌려줬다. 그런데 이 방법도 물론 가능은 하겠지만 아무리 생각해도 좋은 방법은 아닌 것 같았다. input창들이 단순한 UI 뿐만이 아니라 이 값들을 따로 저장하고, 또 백엔드에 보내줘야하니까.

그래서 이런 식으로 코드를 수정했다. 이번에도 실수가 있었다. 글을 읽다가 바로 틀린 부분을 찾아내시는 분들이 있을 것 같다. ㅎㅎ

이렇게 전부 useState로 값이 저장되게 한 다음


  const [form, setValues] = useState({
    userId: "",
    password: "",
    newPassword: "",
    checkPassword: "",
    nameKor: "",
    nameEn: "",
    nickname: "",
    idNumber: "",
    phoneNumber: "",
    emergencyNumber: "",
    businessEmail: "",
    personalEmail: "",
    bankAccount: "",
    passport: ""
  });

return 부분에 귀찮지만 이런 식으로 하나하나 컴포넌트를 불러왔다.

    <UserInfo
      name="userId"
      title="아이디"
      type="text"
      value={form.userId}
      onChange={handleInput}
    />
    
   <UserInfo
      name="password"
      title="비밀번호"
      type="password"
      value={form.password}
      onChange={handleInput}
    />

react의 재사용성을 거의 활용하지 못하는 것 같아서( 디자인적으로는 재활용하긴 하지만) 마음이 안 좋다. 일단은 시간 내에 완성하고 리팩토링 하면서 다시 수정해보려한다.

아무튼 onChange가 될 때마다 작동하는 handleInput의 경우 다음과 같이 작성했다. 이런 식으로 [e.target.name]: e.target.value 라고 쓰면 일일이 함수를 만들지 않고 하나의 함수로 setState를 해줄 수 있다.


  const handleInput = (e) => {
    setValues({
      [e.target.name]: e.target.value
    });
  };

UserInfo 컴포넌트의 구조는 다음과 같다.

import React from "react";
import "./UserInfo.scss";
const UserInfo = ({ title, type, essential, placeholder }) => {
  return (
    <div className="userInfo">
      <div className="userInputArea">
        <div className="inputLabel">
          <span>{essential}</span>
          <p>{title}</p>
        </div>
        <input type={type} placeholder={placeholder} />
      </div>
    </div>
  );
};
export default UserInfo;

이렇게 식을 다 작성한 다음 개발자 도구를 열어서 확인해봤는데

아뿔싸..? 값이 들어오지 않는다. console.log로 e.target.name이나 e.target.value 둘다 찍어보았지만 전혀 어떤 값도 들어오지 않았다.


대체 뭐가 문제지 ????!!

문제는, return 부분에 있었다. 컴포넌트 자체에 onChange를 부여했으니 handleInput이라는 함수가 작동할 리가 없었다.

수정한 코드

   <UserInfo
      name="password"
      title="비밀번호"
      type="password"
      value={form.password}
      handleInput={handleInput}
    />

return 부분을 이렇게 수정해서 props로 내려주고

import React from "react";
import "./UserInfo.scss";
const UserInfo = ({ name, title, type, essential, placeholder, handleInput }) => {
  return (
    <div className="userInfo">
      <div className="userInputArea">
        <div className="inputLabel">
          <span>{essential}</span>
          <p>{title}</p>
        </div>
        <input name= {name}type={type} placeholder={placeholder} onChange={handleInput} />
      </div>
    </div>
  );
};
export default UserInfo;

UserInfo에서 이렇게 받아오는 식으로 수정했다.

결과는 성공! 이제 값을 관리하는 것까지는 성공했다. 남은 것은 백엔드에게 보내주는 일 뿐이다.

profile
공부하는 즐거움
post-custom-banner

0개의 댓글