티스토리 뷰
Custom Hooks
- Custom Hooks는 React에서 재사용 가능한 로직을 추상화하여 함수 컴포넌트에서 쉽게 사용할 수 있도록 도와주는 기능입니다.
- 이를 이용하면, 상태관리 로직의 재활용이 가능하고, 클래스 컴포넌트보다 적은 양의 코드로 동일한 로직을 구현할 수 있으며, 함수형으로 작성하기 때문에 보다 명료하다는 장점이 있습니다.
- Custom Hooks을 사용하기 위해서는 몇 가지 규칙이 존재합니다.
- 우선, Custom Hooks의 함수는 항상 "use"로 시작해야 React가 Hook임을 인식합니다.
- Custom Hook으로 만들 때 함수는 조건부 함수, 즉 return 하는 값은 조건부여서는 안 됩니다. 이는 Hook의 순서가 항상 동일 순서로 호출되어하고, Custom Hook 또한 Hook이기에 이 규칙을 따라야 합니다.
- Custom Hook은 useState와 같은 React 내장 Hook을 사용하여 작성할 수 있고, 심지어는 자신이 직접 만든 Custom Hook도 같이 사용가능합니다.
- 일반 함수 내부에서는 React 내장 Hook을 불러 사용할 수 없지만 Custom Hook에서는 가능하다는 것 또한 하나의 장점입니다. 이를 통해, 기존에 일반 함수에서 사용 불가능한 React 내장 Hook을 Custom Hook으로 만들어 사용할 수 도 있습니다.
Custom Hook의 예시
다음은 Custom Hook의 예시입니다.
const useFetch = ( initialUrl:string ) => {
const [url, setUrl] = useState(initialUrl);
const [value, setValue] = useState('');
const fetchData = () => axios.get(url).then(({data}) => setValue(data));
useEffect(() => {
fetchData();
},[url]);
return [value];
};
export default useFetch;
- 위의 hook은 useFetch로, url을 인자로 fetch할 때 쓸 수 있는 hook입니다.
- 이렇게 fetch로 받은 데이터를 리턴합니다.
- 또한 useEffect를 사용하여, url이 변경될 때마다 호출되도록 설정되었습니다.
import { useState, useCallback } from 'react';
function useInputs(initialForm) {
const [form, setForm] = useState(initialForm);
// 변경 이벤트 핸들러
const onChange = useCallback(e => {
const { name, value } = e.target;
setForm(form => ({ ...form, [name]: value }));
}, []);
// 초기화 함수
const reset = useCallback(() => setForm(initialForm), [initialForm]);
return [form, onChange, reset];
}
export default useInputs;
- form 입력 관련 상태와 함수들을 관리하는 데 사용되는 useInputs입니다.
- 초기 데이터를 저장하고, 반환한 onChange로 이벤트가 발생하면, input안에 존재하는 값을 setForm으로 form에 저장합니다.
- 또한, reset함수가 달려 있어, form에서 입력을 끝내고 데이터를 처리한 후 초기값으로 초기화시켜줍니다.
실습
import "./styles.css";
import { useEffect, useState } from "react";
export default function App() {
const [data, setData] = useState();
useEffect(() => {
fetch("data.json", {
headers: {
"Content-Type": "application/json",
Accept: "application/json"
}
})
.then((response) => {
return response.json();
})
.then((myJson) => {
setData(myJson);
})
.catch((error) => {
console.log(error);
});
}, []);
return (
<div className="App">
<h1>To do List</h1>
<div className="todo-list">
{data &&
data.todo.map((el) => {
return <li key={el.id}>{el.todo}</li>;
})}
</div>
</div>
);
}
해당 코드에서 데이터를 url로 데이터를 fetch하는 부분만을 Hook으로 만들면 다음과 같습니다.
import "./styles.css";
import useFetch from "./util/useFetch";
import { useEffect, useState } from "react"
const useFetch = (fetchUrl) => {
const [data, setData] = useState();
useEffect(() => {
fetch(fetchUrl, {
headers: {
"Content-Type": "application/json",
Accept: "application/json"
}
})
.then((response) => {
return response.json();
})
.then((myJson) => {
setData(myJson);
})
.catch((error) => {
console.log(error);
});
}, [fetchUrl]);
return data;
};
export default function App() {
const fetchdata = useFetch("data.json");
return (
<div className="App">
<h1>To do List</h1>
<div className="todo-list">
{fetchdata &&
fetchdata.todo.map((el) => {
return <li key={el.id}>{el.todo}</li>;
})}
</div>
</div>
);
}
'개발 > React' 카테고리의 다른 글
gh-pages로 react 플젝를 배포해 보자 (0) | 2023.10.20 |
---|---|
코드 분할 (0) | 2023.05.22 |
React Hooks(useMemo, useCallback) (0) | 2023.05.20 |
React Diffing Algorithm (0) | 2023.05.19 |
가상 DOM (1) | 2023.05.19 |
댓글