본문 바로가기

카테고리 없음

[React & Next.js] react-hook-form 효율적으로 사용해보기 - 1

react-hook-form

최근 회원가입을 구현 하면서 효율적으로 사용하고 있는 react의 라이브러리 react-hook-form을 복습 합니다

사용해보고 느낀 react-hook-form의 장점

  • 비제어 컴포넌트로 폼을 관리할 수 있습니다
  • 에러를 효율적으로 관리 할 수 있습니다(실시간 유효성검사)
  • input마다 값을 받는 state를 만들지 않아도 됩니다 (객체로 관리하는 state도)
  • 지속적으로 업데이트를 꾸준히 해주는거 같습니다
  • 공식문서가 친절합니다

바로 사용해보기

최소단위의 로그인 폼을 구현 해봅니다

next.js로 프로젝트 시작하기

npx create-next-app@latest --typescript

next.js 프로젝트의 설정을 물어보는데 프로젝트 이름, 테일윈드css(no), app 디렉토리(no), src 디렉토리(no) 해주시면 됩니다

그리고 react-hook-form을 설치합니다

npm intall react-hook-form
yarn add react-hook-form

우선 간단한 로그인창을 react-hook-form을 사용하지 않고 일반적인 next.js로 만들어 보겠습니다

저는 css로 styled-components를 사용합니다

export default function Home() {
  return (
    <Container>
      <Title>Login</Title>
      <FormInput>
        <InputBox>
          <h4>아이디</h4>
          <input type="text" />
        </InputBox>
        <InputBox>
          <h4>비밀번호</h4>
          <input type="text" />
        </InputBox>
        <input type="submit" value="확인" />
      </FormInput>
    </Container>
  );
}

// styled-components 스타일컴포넌트

const Container = styled.section`
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 20px;
  width: 400px;
  height: 300px;
  padding-top: 30px;
  border: 1px solid rgb(148, 199, 182);
  border-radius: 8px;
`;

const FormInput = styled.form`
  display: flex;
  flex-direction: column;
  gap: 20px;
`;

const Title = styled.h1`
  text-align: center;
`;

const InputBox = styled.article``;

아이디와 비밀번호를 입력할 수 있는 로그인창을 만들었습니다

먼저 리액트에서 많이 사용하는 방법으로 State를 통한 제어 컴포넌트 관리를 하는 방법을 보도록 하죠

제어 컴포넌트를 통한 input form 관리방법

export default function Home() {
  const [userInfo, setUserInfo] = useState<UserInfoType>({
    email: "",
    password: "",
  });

  // onChange
  const handleChange = (event: ChangeEvent<HTMLInputElement>) => {
    const { name, value } = event.target;

    if (name === "email") {
      setUserInfo({ ...userInfo, email: value });
    } else if (name === "password") {
      setUserInfo({ ...userInfo, password: value });
    }
  };

  // 전송
  const handleSubmit = (event: { preventDefault: () => void }) => {
    setUserInfo({ email: "", password: "" });
    event.preventDefault();
  };

  return (
    <Container>
      <Title>Login</Title>
      <FormInput onSubmit={handleSubmit}>
        <InputBox>
          <h4>아이디</h4>
          <input type="text" name="email" onChange={handleChange} />
        </InputBox>
        {userInfo.email}

        <InputBox>
          <h4>비밀번호</h4>
          <input type="text" name="password" onChange={handleChange} />
        </InputBox>
        {userInfo.password}
        <input type="submit" value="초기화 전송" />
      </FormInput>
    </Container>
  );
}

useState Hook을 통해 email과 password의 값을 관리할 상태를 만들어주고 input name의 값의 따라 email과 password의 값을 각각 저장해주어 handleSubmit() 전송을 통해 값을 보내는 방식을 이용 하였습니다

가장 보편적으로 많이 사용하며 State를 객체로 관리하거나 useState를 email, password 각각 생성하여 관리할 수도 있습니다

es6 문법을 통해 코드를 더욱 간결하게 만들겠습니다

const [userInfo, setUserInfo] = useState<UserInfoType>({
  email: "",
  password: "",
});

const { email, password } = userInfo;

// onChange
const handleChange = (event: ChangeEvent<HTMLInputElement>) => {
  const { name, value } = event.target;

  setUserInfo({
    ...userInfo, // 기존의 input 객체를 복사한 뒤
    [name]: value, // name 키를 가진 값을 value 로 설정
  });
};

// 전송
const handleSubmit = (event: { preventDefault: () => void }) => {
  setUserInfo({ email: "", password: "" });
  event.preventDefault();
};

이렇게만 하여도 같은 기능을 훨씬 가독성 좋게 만들 수 있겠네요

그런데 react-hook-form을 써야하는 이유가 있을까를 생각해본다면 제어 컴포넌트로 state를 만들어 관리를 하지 않아도 된다는 점이 렌더링 성능향상에 도움을 줄 수 있고

더 나아가 전송을 할때 조건을 주어 전송을 막아야하고, 에러 메시지를 띄워줘야하고, 이메일 유효성검사, 패스워드 유효성 검사, 이걸 실시간으로 구현해야하고 등등 여러가지 부가적인 조건을 갖추어 하나의 로그인 로직을 구현해야 할때 매우 유용하게 쓸 수 있는게 react-hook-form 입니다

다음 글은 react-hook-form을 이용하여 같은 기능을 구현해 보면서 react-hook-form의 장점을 알아보도록 하겠습니다