본문 바로가기
웹/(React)리액트

(React) 리액트 커스텀 훅 custom hook 사용법+input 초기화 까지 - input

by 공부가싫다가도좋아 2022. 9. 24.
반응형

<포스팅 요약>

1. 커스텀 훅 사용전 코드

2. 커스텀 훅 사용한 코드

3. 커스텀 훅 사용 이유

3-1 커스텀 훅 사용전 - 회원가입 폼

3-2 커스텀 훅 사용후 - 회원가입 폼


1.  커스텀 훅 사용전 코드 

import React, { useCallback, useState } from "react";

const Home2 = () => {
  const [text, setText] = useState(""); //text값 초기화
  const onChange = useCallback(
    (e) => {
      setText(e.target.value);
    },
    [text]
  );
  const okBtn = useCallback(
    (e) => {
      console.log("nickname:", text);
      setText(""); //버튼 클릭시 text값="" (즉 text값 초기화)
    },
    [text]
  );
  return (
    <div>
      <input type="text" name="text" value={text} onChange={onChange} />
      <button onClick={okBtn}>input 초기화</button>
    </div>
  );
};

export default Home2;

 


2. 커스텀 훅 사용한 코드

*커스텀훅 사용시 파일 이름은 "use"로 시작(예: useInput.js, useFetch.js ...)

useInput.js

import { useCallback, useState } from "react";

const useInput = (initialValue = null) => {
  const [data, setData] = useState(initialValue); //data에 들어가는 값 초기화

  const handler = useCallback(
    (e) => {
    
      //Home.js의 input에서 name값과 value값 불러옴
      const { name, value } = e.target; 
      
      //...data를 하는 이유는 
      //Home.js에서는 input이 하나밖에 없지만, 
      //input이 여러개인 경우를 위해서. (3번의 상세설명 참고하세요.)
      setData({ ...data, [name]: value }); 
      
    },
    [data]
  );
  
  const reset = useCallback(() => { //initialValue값으로 data초기화
    setData(initialValue);
  }, [initialValue]);
  return [data, handler, reset];
};

export default useInput;

 

Home.js

import React, { useCallback } from "react";
import useInput from "../useHook/useInput";

const Home = () => {
  const [nickname, onChange, reset] = useInput({ text: "" });
  const okBtn = useCallback(
    (e) => {
      console.log("nickname:", nickname.text);
      reset();
    },
    [nickname.text]
  );
  return (
    <div>
      <input
        type="text"
        name="text"
        value={nickname.text}
        onChange={onChange}
      />
      <button onClick={okBtn}>input 초기화</button>
    </div>
  );
};

export default Home;

 


3. 커스텀 훅 사용 이유

회원가입폼을 예로 들어봅시다.

회원가입 폼에서 받는 값이 nickname, id, password, phone 이라고 할때 

커스텀 훅을 사용하지 않을경우 아래와 같은 코드를 작성하게 됩니다.

(값의 유효성 체크는 다루지 않겠습니다.)

더보기

유효성 체크란?

input 양식 체크를 말합니다.

(+ 정해진 규칙에 알맞게 입력했는지 체크하는 것을 말함.)

예 1)

phone의 input에서 숫자만 받고 싶은 경우,

숫자가 아닌경우를 체크하는 코드를 작성했을 경우, 유효성 체크를 했다 라고 합니다.

 

예 2)

password의 input에서 특수문자를 필수로 넣어야 된다고 정했을때,

특수문자를 넣었는지 안넣었는지 체크해주는 경우 유효성 체크를 했다 합니다. 

 

만들을 화면

 

3-1 커스텀 훅 사용전 - 회원가입 폼

Signup.js

import React, { useState, useCallback } from "react";

const Test = () => {
  const [nickname, setNickName] = useState("");
  const [id, setId] = useState("");
  const [password, setPassword] = useState("");
  const [phone, setPhone] = useState("");

  const reset = useCallback(() => {
    setNickName("");
    setId("");
    setPassword("");
    setPhone("");
  }, [nickname, id, password, phone]);
  const onChange_nickname = useCallback(
    (e) => {
      setNickName(e.target.value);
    },
    [nickname]
  );
  const onChange_id = useCallback(
    (e) => {
      setId(e.target.value);
    },
    [id]
  );
  const onChange_password = useCallback(
    (e) => {
      setPassword(e.target.value);
    },
    [password]
  );
  const onChange_phone = useCallback(
    (e) => {
      setPhone(e.target.value);
    },
    [phone]
  );

  const signUp = useCallback(
    (e) => {
      e.preventDefault();
      console.log("닉네임:", nickname);
      console.log("아이디:", id);
      console.log("비밀번호:", password);
      console.log("전화번호:", phone);
      reset(); //input값 초기화
    },
    [nickname, id, password, phone]
  );

  return (
    <form
      onSubmit={signUp}
      autoComplete="off"
      style={{
        display: "flex",
        flexDirection: "column",
        width: "500px",
        margin: "auto",
      }}
    >
      <h2>회원가입</h2>
      <label style={{ marginTop: "10px" }} for="nickname">
        닉네임
      </label>
      <input
        type="text"
        name="nickname"
        value={nickname}
        onChange={onChange_nickname}
        autoFocus
      />
      <label style={{ marginTop: "10px" }} for="nickname">
        아이디
      </label>
      <input type="text" name="id" value={id} onChange={onChange_id} />
      <label style={{ marginTop: "10px" }} for="nickname">
        비밀번호
      </label>
      <input
        type="password"
        name="password"
        value={password}
        onChange={onChange_password}
      />
      <label style={{ marginTop: "10px" }} for="nickname">
        전화번호
      </label>
      <input type="text" name="phone" value={phone} onChange={onChange_phone} />
      <button style={{ marginTop: "10px" }} type="submit">
        회원가입
      </button>
    </form>
  );
};

export default Test;

 

3-2 커스텀 훅 사용후 - 회원가입 폼

** useInput은 2번째의 "2.커스텀 훅 사용한 코드" useInput.js를 그대로 사용합니다.

import React, { useCallback } from "react";
import useInput from "../useHook/useInput";

const Test = () => {
  const [data, onChange, reset] = useInput({
    nickname: "",
    id: "",
    password: "",
    phone: "",
  });

  const signUp = useCallback(
    (e) => {
      e.preventDefault();
      console.log("닉네임:", data.nickname);
      console.log("아이디:", data.id);
      console.log("비밀번호:", data.password);
      console.log("전화번호:", data.phone);
      reset(); //input값 초기화
    },
    [data.nickname, data.id, data.password, data.phone]
  );

  return (
    <form
      onSubmit={signUp}
      autoComplete="off"
      style={{
        display: "flex",
        flexDirection: "column",
        width: "500px",
        margin: "auto",
      }}
    >
      <h2>회원가입</h2>
      <label style={{ marginTop: "10px" }} for="nickname">
        닉네임
      </label>
      <input
        type="text"
        name="nickname"
        value={data.nickname}
        onChange={onChange}
        autoFocus
      />
      <label style={{ marginTop: "10px" }} for="nickname">
        아이디
      </label>
      <input type="text" name="id" value={data.id} onChange={onChange} />
      <label style={{ marginTop: "10px" }} for="nickname">
        비밀번호
      </label>
      <input
        type="password"
        name="password"
        value={data.password}
        onChange={onChange}
      />
      <label style={{ marginTop: "10px" }} for="nickname">
        전화번호
      </label>
      <input type="text" name="phone" value={data.phone} onChange={onChange} />
      <button style={{ marginTop: "10px" }} type="submit">
        회원가입
      </button>
    </form>
  );
};

export default Test;

각 input마다 onChange함수를 따로 만들지 않아도 되고,

상태들이 한곳에 모여있기 때문에, 관리를 하기 한결 더 편해졌습니다.

(** 중복코드 줄일 수 있는 것이 제일 큰 장점)

 

이와 같이 같은 형식일 경우 useInput.js를 import하여 바로 여러곳에서 사용할 수 있습니다.

 

반응형

댓글