23/12/7

Laejun Kim·2023년 12월 7일
0

TIL

목록 보기
51/89

개인프로젝트

못난 내 코드(2/3)

state관리

<내 코드>

//src>components>auth>SignInForm.jsx

// (전략)
  const [id, setId] = useState("");
  const [pw, setPw] = useState("");
  const [nickName, setNickName] = useState("");

//(중략)
onChange={(e) => {
              setPw(e.target.value);
            }}
onChange={(e) => {
              setNickName(e.target.value);
            }}
onChange={(e) => {
              setId(e.target.value);
            }}
//(후략)

<모범 코드> 류제천 튜터님

//src>hooks>useForm.js
const { useState } = require("react");

const useForm = (initialState = {}) => {
  //={} 해준건 그냥 기본값 설정임. 실제로는 호출부에서 인자로 받음
  const [formState, setFormState] = useState(initialState);
  const onChangeHandler = (event) => {
    const { name, value } = event.target;
    setFormState((prev) => ({ ...prev, [name]: value }));
  };
  const resetForm = () => {
    setFormState(initialState);
  };

  return { formState, onChangeHandler, resetForm };
};

export default useForm;

//src>pages>Login.jsx
import useForm from "hooks/useForm";
//(중략)
const { formState, onChangeHandler, resetForm } = useForm({
    id: "",
    password: "",
    nickname: "",
  });
const { id, password, nickname } = formState;
//(중략)
<Input
          name="password"
          onChange={onChangeHandler}
          value={password}
          placeholder="비밀번호 (4~15글자)"
          minLength={4}
          maxLength={15}
        />

무엇이 다른가?

  1. State 통합
    내 코드는 id/pw/nickname 에 대하여 각각 하나씩의 state를 만들고 이것을 각 Input 컴포넌트에서 onChange 에 엮어서 제어하고 있다. 이에 반해 모범 코드에서는 id/pw/nickname 세가지 필드를 가진 객체로 state 하나를 관리하고 있다.

  2. 커스텀 훅
    커스텀 훅을 만들어서 코드를 간결하게 유지하는 것 또한 주목할 만하다. onChangeHandler 함수도 커스텀 훅 내에서 정의하고 이것을 객체에 담아서 리턴해주면 호출부에서 그 함수를 그대로 쓸수 있다는 것은 기억해 두어야 한다. 애초에 호출부에서 객체구조분해 할당으로 커스텀훅으로부터 리턴 받은 것들을 편하게 사용할 수 있게 한 것도 본받을 만하다.

  3. Onchange 핸들러 통합
    내 코드에서는 세개의 onChange 핸들러를 사용하고 있는 반면에 모범 코드에서는 onChange 핸들러 하나를 사용하고 있다.

    id, pw, nickname 이 각각 다른 필드인데 어떻게 하나의 함수로 이 변화를 처리하는 것일까?

    { ...prev, [name]: value }그건 이 부분을 보면 알 수 있는데, 변경 되지 않은 필드에 대해서는 ...prev로 그대로 받고 변경되는 함수에 대해서만 값을 갱신할 수 있도록 [name]:value로 작성되었다. name 은 상태 객체의 필드명인 동시에 Input 태그의 property 이기도 하다. 애초에 처음 코드를 작성할 때부터 이렇게 사용할 의도로 각 Input 태그에 name 프러퍼티를 부여하고 그것과 같은 이름으로 state 객체의 필드명을 지정한 것이다.

    참고로 name 은 e.target.value 했던 것과 동일하게 e.target.name 으로 접근할 수 있으며, 여기서도 접근의 용이성을 위해 onChange 핸들러 내에서 const { name, value } = event.target; 이렇게 객체구조분해할당을 하고 있다.

0개의 댓글