이번 포스팅에서는 React에서 제공해주는 내장 Hook이 아닌 자신만의 Hook을 만드는 방법에 대해 다뤄보고자 한다. React에는 "사용자 정의 Hook" 이라는 개념이 존재한다. 이는 React에서 제공해주는 Hook이 아닌 사용자가 직접 만든 Hook을 지칭하며 "사용자 정의 Hook" 혹은 "커스텀 Hook (Custom Hook)"이라 불린다. 자신만의 Hook을 만들어서 사용하면 컴포넌트 로직을 함수로 뽑아내어 재사용 할 수 있게 된다는 점에서 상당한 이점이 있다.
Custom Hook
커스텀 Hook을 사용하면 무엇을 매개변수로 받을 것인지, 무엇을 반환할 것인지 직접 결정할 수 있다. 그리고 커스텀 Hook 안에서 다른 Hook을 호출하는 것 역시 가능하다. 다시 말해, 커스텀 Hook은 보통의 함수와 마찬가지이다. 커스텀 Hook을 만들어서 사용할 때 한가지 주의할 점이 있다면 커스텀 Hook의 이름이 "use"로 시작되어야 한다는 점이다. 이름은 반드시 use로 시작해야 하는데 그래야만 Hook 규칙이 적용되는지를 파악할 수 있기 때문이다.
아래의 코드는 useInput 이라는 이름의 간단한 커스텀 Hook을 만들어서 사용해 본 예제 코드이다.
import React, { useState } from 'react'
const useInput = () => {
const [value, setValue] = useState('')
const onChange = e => {
setValue(e.target.value)
}
return {
value,
onChange
}
}
const Form = () => {
const id = useInput()
const pw = useInput()
const handleSubmit = e => {
e.preventDefault()
}
return (
<form onSubmit={handleSubmit}>
<h2>로그인</h2>
<ul>
<li>
<label htmlFor='userid'>아이디</label>
<input
type='text'
name='userid'
{...id}
/>
</li>
<li>
<label htmlFor='userpw'>패스워드</label>
<input
type='password'
name='userpw'
{...pw}
/>
</li>
<li>
<input type='submit' valeu='로그인' />
</li>
</ul>
</form>
)
}
export default Form;
useInput 함수 안에서 value 라는 상태와 onChange 함수를 정의했으며 useInput( )의 return 값으로는 { value, onChange }를 반환하고 있다. 함수 컴포넌트 Form 안에서 useInput이 사용되는 방식을 살펴보면 const id = useInput( ) , const pw = useInput( ) 과 같이 useInput( )의 return 값을 id 와 pw 변수에 할당한 후 React 엘리먼트 안에서 <input { ...id } /> , <input { ...pw } /> 와 같이 사용되고 있다.
이러한 방식으로 사용이 가능한 이유는 React 엘리먼트가 사실은 JavaScript 객체이기 때문이다. 함수 컴포넌트에서 JSX로 작성된 <input type='text' name='userid' { ...id } /> 의 내용은 babel에 의해 아래와 같은 object로 변환된다.
{
type: 'input',
props: {
type: 'text',
name: 'userid',
onChange: () => { },
value: ''
}
}
그리고 React는 이러한 object를 HTML로 변환해준다. 다시 말하지만, { ...id } , { ...pw } 와 같은 구조분해할당문을 React 엘리먼트 안에서 사용할 수 있는 이유는 기본적으로 React 엘리먼트가 객체 형태이기 때문이다.
커스텀 Hook이라고 해서 딱히 새로울 것은 없다. 단지 이름이 use로 시작하는 JavaScript 함수일 뿐이다.
'React' 카테고리의 다른 글
React - react-redux (0) | 2022.05.03 |
---|---|
React - react-router-dom (0) | 2022.05.02 |
React - useCallback & useMemo (0) | 2022.04.30 |
React - useContext & useReducer (1) | 2022.04.29 |
React - Lifecycle & useEffect (0) | 2022.04.26 |