[React]Custom Hook

JH Cho·2022년 10월 2일
0

React

목록 보기
19/27

React에서 관심사의 분리

Hook 등장 이전

  • React의 관심사

    • 로직- API 호출, state변경, 이벤트 핸들링 등
    • UI - JSX
  • Presentational - Container 퍁ㄴ

  • 로직을 담당하는 컴포넌트(Container)와 UI를 담당하는 컴포넌트(Presentational)를 분리해서 관리

Hook 등장 이후

  • Hook 등장 이후로 Container-Presentational 패턴 더 이상 권장 X
  • Hooks를 이용해 함수 컴포넌트에서도 로직을 작성할 수 있게 됨.
  • 하지만, 여전히 함수 컴포넌트 내부에 로직과 UI가 뒤섞여서 존재
    • 컴포넌트 내부의 코드가 길어져서 가독성이 떨어짐
    • 작성한 로직을 다른 컴포넌트에서도 동일하게 사용해야 하는 경우 동일한 다른 컴포넌트에서도 똑같이 작성해야 됨 -> 중복 발생

정의 및 특징

  • Custom Hook은 이름이 use로 시작하고 다른 Hooks를 호출하는 JS 함수
  • Custom Hook을 사용하면 컴포넌트에 결합되어 있던 state와 effect를 함수 단위로 추출 가능
  • Custom Hook의 특징
    • 로직의 복잡한 내부 구조를 숨기고 단순한 함수의 호출 형태로 사용 가능
    • 함수를 여러 컴포넌트에서 호출하는 방식으로 재사용 가능

실습

예시1)

// UserStatus.js (예시 코드)

import React, { useState } from 'react';

const UserStatus = () => {
  const [isActive, setIsActive] = useState(false);

  const handleToggle = () => {
    setIsActive((prev) => !prev);
  };

  return (
    <>
      <h1>현재 사용자의 상태입니다.</h1>
      <span>{isActive ? '사용 중' : '사용 안 함'}</span>
      <button onClick={handleToggle}>사용 상태 변경</button>
    </>
  );
};

export default UserStatus;

분리해보기

// ./useToggle.js (로직 부분 예시 코드)

import { useState } from 'react';

const useToggle = (initialValue = false) => {  // 아무 값도 안들어오면 undefined 뜨니까 기본값은 
  //아무것도 안들어오면 false 기본값 세팅
  const [state, setState] = useState(initialValue);

  const handleToggle = () => {
    setState((prev) => !prev);
  };

  return [state, handleToggle];
}; //배열이나 객체를 리턴해야 함.

export default useToggle;

기존 코드 수정

// ./UserStatus.js (UI 부분 예시 코드)

import React from 'react';
import useToggle from './useToggle';

const UserStatus = () => {
  const [isActive, changeStatus] = useToggle();
  // 커스텀훅의 [state, handleToggle]을 
  // 구조분해할당해줌.

  return (
    <>
      <h1>현재 사용자의 상태입니다.</h1>
      <span>{isActive ? '사용 중' : '사용 안 함'}</span>
      <button onClick={changeStatus}>사용 상태 변경</button>
    </>
  );
};

export default UserStatus;

예시2)
users.json [김코드, 김개발]

function UserList(){
  const [users, setUsers] = useState([]);
  
  useEffect(()=>{
    fetch("/data/users.json")
    .then((res)=> res.json())
    .then(setUsers);
  }, []);
  
  return (
    <ul>
    	{users.map((user) =>(
    		<li key={user}>user: {user}</li>
		))}
	</ul>
  );
}

export default UserList;

커스텀훅

const useUsers = ()=>{
  const [users, setUsers] = useState([]);
  
    useEffect(()=>{
    fetch("/data/users.json")
    .then((res)=> res.json())
    .then(setUsers);
  }, []);
  return users;
}
-------
  // 기존 컴포넌트
 const users = useUsers();

커스텀훅 관리 요령

여러 컴포넌트에서 사용된다면 src에 hook폴더를 따로 만들어서 관리

하나의 컴포넌트 전용이라면 해당 폴더 내에서 관리

profile
주먹구구식은 버리고 Why & How를 고민하며 프로그래밍 하는 개발자가 되자!

0개의 댓글