커스텀 훅을 통해, 다른 컴포넌트에서 사용할 수 있는 로직을 커스텀 훅으로 아웃소싱할 수 있으며, 이를 통해 다양한 컴포넌트에서 호출이 가능하다.
정규 함수와 특수 함수의 관계와 같이 커스텀 훅 함수에서는 리액트 훅과 다른 훅을 사용할 수 있다.
-
=> +
로 바뀌는 것 뿐이다.import { useState, useEffect } from 'react';
import Card from './Card';
const BackwardCounter = () => {
const [counter, setCounter] = useState(0); // <== from here
useEffect(() => {
const interval = setInterval(() => {
setCounter((prevCounter) => prevCounter - 1);
}, 1000);
return () => clearInterval(interval);
}, []); // <== to there
return <Card>{counter}</Card>;
};
export default BackwardCounter;
use-뭐뭐뭐
라고 원하는 이름의 파일을 만들자use--
접두어가 붙어야한다.리액트에게 이 함수가 custom hook
임을 알려주며 이는 리액트가 해당 함수를 "훅의 규칙"에 따라 사용하겠다고 보장해주는 것이다. 즉, 이 커스텀 훅을 내장 훅과 같은 방식으로 쓰겠다는 것이다.
use-
접두어는 리액트가 요구하는 것으로 만약 그렇지 않고 리액트 훅을 커스텀 훅에서 사용하면서, 커스텀 훅을 잘못된 곳에서 사용하게 된다면 내장 훅 역시 잘못된 곳에서 쓸 수 있음을 내포하게 된다.
이 것이 use로 이름이 시작하게끔 하는 이유로 이렇게 해야 리액트가 확인을 하고 프로젝트 셋업이 함수가 use로 시작하면서 훅의 규칙을 위반한 것이 발견되었을 때 경고를 보낼 수 있기 때문이다
import {useState, useEffect} from "react"
const useCounter = () => {
const [counter, setCounter] = useState(0);
useEffect(() => {
const interval = setInterval(() => {
setCounter((prevCounter) => prevCounter - 1);
}, 1000);
return () => clearInterval(interval);
}, []);
return counter;
};
export default useCounter
import useCounter from '../hooks/use-counter';
import Card from './Card';
const ForwardCounter = () => {
const counter = useCounter();
return <Card>{counter}</Card>;
};
export default ForwardCounter;
만약 컴포넌트 안에서 커스텀 훅을 호출하고 이 컴포넌트가, 예를 들어 어떤 state나 effect를 사용한다면, 그 state나 effect가 커스텀 훅을 사용하고 있는 컴포넌트에 묶이게 된다.
즉, 커스텀 훅의 state나 effect가 해당 컴포넌트에 생성되어 존재한다는 뜻이다.
만약에 여러 컴포넌트에서 각각 같은 커스텀 훅을 사용한다면 state나 effect를 공유하는 것이 아닌 본인의 독자적인 state와 effect가 생성되어 "tied" 된다는 뜻이다.
3.
=> 에서 확장하여 매개변수로 하여금 코드에 유동성을 넣어준다.import {useState, useEffect} from "react"
const useCounter = (counterUpdateFn) => {
const [counter, setCounter] = useState(0);
useEffect(() => {
const interval = setInterval(() => {
setCounter(counterUpdateFn);
}, 1000);
return () => clearInterval(interval);
}, [counterUpdateFn]);
return counter;
};
export default useCounter
(2) boolean flag로 통제하는 경우
import {useState, useEffect} from "react"
const useCounter = (forwards = true) => {
const [counter, setCounter] = useState(0);
useEffect(() => {
const interval = setInterval(() => {
if(forwards){
setCounter((prevCounter)=>prevCounter + 1);
}else{
setCounter((prevCounter)=>prevCounter - 1);
}
}, 1000);
return () => clearInterval(interval);
}, [forwards]);
return counter;
};
export default useCounter
또 하나 신경써야할 점은 여기에서 사용하고 있는 이 매개변수들과 의존성이다.
이는 useEffect 함수에서 정의된 것이 아니고 또 커스텀 훅 외부에서 설정된 것도 아니다.
대신에, 이는 매개변수로서 받게 되는 값이기 때문에 이를 의존성으로 추가해야 한다.
따라서 매개변수를 의존성으로 추가하여 의존성 변경이 발생할 때마다 useEffect 함수가 재실행하게 한다.