React Hooks API 시작하기
게시 됨: 2022-03-10React 16.8이 2019년 2월 초에 공식적으로 출시되었을 때 클래스를 작성하지 않고도 React의 상태 및 기타 기능을 사용할 수 있는 추가 API와 함께 제공되었습니다. 이 추가 API를 Hook 이라고 하며 오픈 소스 프로젝트에서 프로덕션 애플리케이션에 사용되는 것에 이르기까지 React 생태계에서 인기를 얻고 있습니다.
React Hooks는 완전히 옵트인되어 있어 기존 코드를 다시 작성하는 것이 불필요하고 주요 변경 사항이 포함되어 있지 않으며 React 16.8 릴리스와 함께 사용할 수 있습니다. 일부 호기심 많은 개발자들은 공식적으로 출시되기 전부터 Hooks API를 사용하고 있었지만, 그 당시에는 안정적이지 않았고 실험적인 기능에 불과했습니다. 이제 안정적이며 React 개발자가 사용하는 것이 좋습니다.
참고 : 일반적으로 React 또는 JavaScript에 대해 이야기하지 않습니다. 이 튜토리얼을 진행하면서 ReactJS와 JavaScript에 대한 좋은 지식이 도움이 될 것입니다.
React Hook이란 무엇입니까?
React Hooks는 React 개발자가 기능 구성 요소 내에서 상태 및 수명 주기 메서드를 사용할 수 있도록 하는 내장 기능이며 기존 코드와도 함께 작동하므로 코드베이스에 쉽게 채택할 수 있습니다. Hooks가 대중에게 공개된 방식은 개발자가 기능적 구성 요소에서 상태를 사용할 수 있도록 하는 것이지만 내부적으로는 Hooks가 그보다 훨씬 강력합니다. 이를 통해 React 개발자는 다음과 같은 이점을 누릴 수 있습니다.
- 향상된 코드 재사용
- 더 나은 코드 구성;
- 더 나은 기본값;
- 사용자 정의 후크를 사용하여 비시각적 논리 공유
-
components
트리를 위아래로 유연하게 이동할 수 있습니다.
React Hooks를 사용하면 개발자는 UI 렌더링에서 상태 및 논리 처리에 이르기까지 필요한 거의 모든 작업에 기능 구성 요소를 사용할 수 있습니다. 이는 꽤 깔끔합니다.
React Hooks 출시 동기
ReactJS 공식 문서에 따르면 React Hooks 출시의 동기는 다음과 같습니다.
- 구성 요소 간에 상태 저장 논리를 재사용하는 것은 어렵습니다.
Hooks를 사용하면 아키텍처나 구조를 변경하지 않고 구성 요소 간에 논리를 재사용할 수 있습니다. - 복잡한 구성 요소는 이해하기 어려울 수 있습니다.
구성 요소가 커지고 많은 작업을 수행하면 장기적으로 이해하기 어려워집니다. Hooks는 특정 단일 구성 요소를 수명 주기 메서드에 따라 강제로 분할할 필요 없이 분리된 구성 요소의 어떤 부분이 관련되어 있는지(예: 구독 설정 또는 데이터 가져오기)에 따라 다양한 더 작은 기능으로 분리할 수 있도록 하여 이 문제를 해결합니다. - 수업이 상당히 혼란스럽습니다.
수업은 React를 제대로 배우는 데 방해가 됩니다. 다른 언어와 다른 JavaScript에서this
어떻게 작동하는지 이해해야 합니다. React Hooks는 개발자가 클래스를 사용하지 않고도 최고의 React 기능을 사용할 수 있도록 하여 이 문제를 해결합니다.
후크의 규칙
후크 제안 문서에 설명된 React 핵심 팀에서 명시한 대로 엄격하게 준수해야 하는 두 가지 주요 규칙이 있습니다.
- 루프, 조건 또는 중첩 함수 내에서 Hooks를 사용하지 않도록 하십시오.
- React Functions 내부의 Hook만 사용하세요.
기본 반응 후크
React 16.8과 함께 제공되는 10개의 내장 후크가 있지만 기본(일반적으로 사용되는) 후크는 다음과 같습니다.
-
useState()
-
useEffect()
-
useContext()
-
useReducer()
이들은 코드베이스에 React Hooks를 채택한 React 개발자가 일반적으로 사용하는 4가지 기본 후크입니다.
useState()
useState()
후크를 사용하면 React 개발자가 클래스 구성 요소로 변환할 필요 없이 기능 구성 요소 내부의 상태를 업데이트, 처리 및 조작할 수 있습니다. 아래 코드 스니펫은 간단한 연령 카운터 구성 요소이며 useState()
후크의 기능과 구문을 설명하는 데 사용하겠습니다.
function App() { const [age, setAge] = useState(19); const handleClick = () => setAge(age + 1) return <div> I am {age} Years Old <div> <button onClick={handleClick}>Increase my age! </button> </div> </div> }
눈치채셨다면, 우리의 구성 요소는 매우 단순하고 간결해 보이며 이제는 기능적 구성 요소이며 클래스 구성 요소가 가질 복잡성 수준도 없습니다.
useState()
후크는 초기 상태를 인수로 받은 다음 JavaScript에서 배열 구조화를 사용하여 배열의 두 변수 이름을 what으로 지정할 수 있습니다. 첫 번째 변수는 실제 상태이고 두 번째 변수는 새 상태를 제공하여 상태를 업데이트하기 위한 함수입니다.

이것이 컴포넌트가 React 애플리케이션에서 렌더링될 때 표시되는 방식입니다. "나이 증가" 버튼을 클릭하면 연령 상태가 변경되고 구성 요소는 상태가 있는 클래스 구성 요소처럼 작동합니다.
useEffect()
useEffect()
후크는 효과적인 코드를 포함하는 함수를 허용합니다. 기능 구성 요소에서 돌연변이, 구독, 타이머, 로깅 및 기타 효과와 같은 효과는 기능 구성 요소 내부에 배치할 수 없습니다. 그렇게 하면 UI가 렌더링될 때 많은 불일치가 발생하고 버그가 혼동될 수 있기 때문입니다.
useEffect()
후크를 사용할 때 전달된 효과적인 함수는 렌더링이 화면에 표시된 직후에 실행됩니다. 효과는 기본적으로 React의 기능적 방식과 상당히 다른 UI를 구축하는 명령적인 방식으로 엿볼 수 있습니다.
기본적으로 효과는 주로 렌더링이 완료된 후에 실행되지만 특정 값이 변경될 때 효과를 발동할 수도 있습니다.
useEffect()
후크는 일반적으로 브라우저/DOM API 또는 외부 API와 유사한 데이터 가져오기 또는 구독과의 상호 작용에 사용되는 부작용을 위해 주로 사용됩니다. 또한 React 수명 주기 메서드가 작동하는 방식에 이미 익숙 useEffect()
후크를 구성 요소 탑재 , 업데이트 및 탑재 해제 로 생각할 수도 있습니다. 이 모든 것이 하나의 기능으로 결합됩니다. 기능 구성 요소에서 수명 주기 메서드를 복제할 수 있습니다.
아래 코드 조각을 사용하여 useEffect()
후크를 사용하여 할 수 있는 가장 기본적인 방법을 설명합니다.
1단계: 애플리케이션 상태 정의
import React, {useState} from 'react'; function App() { //Define State const [name, setName] = useState({firstName: 'name', surname: 'surname'}); const [title, setTitle] = useState('BIO'); return( <div> <h1>Title: {title}</h1> <h3>Name: {name.firstName}</h3> <h3>Surname: {name.surname}</h3> </div> ); }; export default App
useState()
후크를 사용하여 기능 구성 요소 내부의 상태를 처리하는 방법에 대한 이전 섹션에서 논의한 것처럼, 우리는 코드 스니펫에서 이를 사용하여 내 전체 이름을 렌더링하는 앱의 상태를 설정했습니다.
2단계: useEffect 후크 호출
import React, {useState, useEffect} from 'react'; function App() { //Define State const [name, setName] = useState({firstName: 'name', surname: 'surname'}); const [title, setTitle] = useState('BIO'); //Call the use effect hook useEffect(() => { setName({FirstName: 'Shedrack', surname: 'Akintayo'}) }, [])//pass in an empty array as a second argument return( <div> <h1>Title: {title}</h1> <h3>Name: {name.firstName}</h3> <h3>Surname: {name.surname}</h3> </div> ); }; export default App
이제 useEffect
후크를 가져 useEffect()
함수를 사용하여 꽤 깔끔하고 간결한 name 및 surname 속성의 상태를 설정했습니다.
빈 배열인 두 번째 인수에서 useEffect
후크를 발견했을 수 있습니다. 이는 종속성 목록이 없는 setFullName
에 대한 호출이 포함되어 있기 때문입니다. 두 번째 인수를 전달하면 업데이트의 무한 체인( componentDidUpdate()
)이 방지되고 useEffect()
후크가 componentDidMount
수명 주기 메서드로 작동하고 트리의 모든 변경 사항에 대해 다시 렌더링하지 않고 한 번만 렌더링할 수 있습니다.
이제 React 앱은 다음과 같아야 합니다.

useEffect
Hook을 사용하는 React 앱(큰 미리보기) 다음과 같이 setTitle()
함수를 호출하여 useEffect()
함수 내에서 응용 프로그램의 title
속성을 변경할 수도 있습니다.
import React, {useState, useEffect} from 'react'; function App() { //Define State const [name, setName] = useState({firstName: 'name', surname: 'surname'}); const [title, setTitle] = useState('BIO'); //Call the use effect hook useEffect(() => { setName({firstName: 'Shedrack', surname: 'Akintayo'}) setTitle({'My Full Name'}) //Set Title }, [])// pass in an empty array as a second argument return( <div> <h1>Title: {title}</h1> <h3>Name: {name.firstName}</h3> <h3>Surname: {name.surname}</h3> </div> ); }; export default App
이제 애플리케이션이 다시 렌더링된 후 새 제목이 표시됩니다.


useContext()
useContext()
후크는 컨텍스트 객체, 즉 React.createContext
에서 반환된 값을 수락한 다음 해당 컨텍스트에 대한 현재 컨텍스트 값을 반환합니다.
이 후크를 사용하면 기능 구성 요소가 React 앱 컨텍스트에 쉽게 액세스할 수 있습니다. useContext
후크가 도입되기 전에 클래스 구성 요소의 일부 공급자로부터 전달된 전역 상태에 액세스하려면 contextType
또는 <Consumer>
를 설정해야 했습니다.
기본적으로 useContext
후크는 다양한 수준을 통해 앱 소품을 수동으로 전달할 필요 없이 앱 전체에서 데이터를 깊이 공유하는 방법인 React Context API와 함께 작동합니다. 이제 useContext()
를 사용하면 Context를 좀 더 쉽게 사용할 수 있습니다.
아래 코드 스니펫은 Context API가 작동하는 방식과 useContext
Hook이 이를 개선하는 방법을 보여줍니다.
컨텍스트 API를 사용하는 일반적인 방법
import React from "react"; import ReactDOM from "react-dom"; const NumberContext = React.createContext(); function App() { return ( <NumberContext.Provider value={45}> <div> <Display /> </div> </NumberContext.Provider> ); } function Display() { return ( <NumberContext.Consumer> {value => <div>The answer to the question is {value}.</div>} </NumberContext.Consumer> ); } ReactDOM.render(<App />, document.querySelector("#root"));
이제 코드 조각을 분해하고 각 개념을 설명하겠습니다.
아래에서 NumberContext
라는 컨텍스트를 생성합니다. { Provider, Consumer }
라는 두 가지 값을 가진 객체를 반환하기 위한 것입니다.
const NumberContext = React.createContext();
그런 다음 생성한 NumberContext
에서 반환된 Provider
값을 사용하여 모든 자식이 특정 값을 사용할 수 있도록 합니다.
function App() { return ( <NumberContext.Provider value={45}> <div> <Display /> </div> </NumberContext.Provider> ); }
이를 통해 생성한 NumberContext
에서 반환된 Consumer
값을 사용하여 모든 자식이 사용할 수 있도록 만든 값을 얻을 수 있습니다. 눈치채셨다면 이 컴포넌트는 props를 얻지 못했습니다.
function Display() { return ( <NumberContext.Consumer> {value => <div>The answer to the question is {value}.</div>} </NumberContext.Consumer> ); } ReactDOM.render(<App />, document.querySelector("#root"));
콘텐츠를 NumberContext.Consumer
에 래핑하고 render props 메서드를 사용하여 값을 검색하고 렌더링하여 App
구성 요소에서 Display
구성 요소로 값을 가져올 수 있었던 방법에 유의하세요.
모든 것이 잘 작동하고 우리가 사용한 render props 방법은 동적 데이터를 처리하는 데 정말 좋은 패턴이지만 장기적으로 익숙하지 않으면 불필요한 중첩과 혼란을 야기합니다.
useContext 메소드 사용하기
useContext
메서드를 설명하기 위해 useContext 후크를 사용하여 Display
구성 요소를 다시 작성합니다.
// import useContext (or we could write React.useContext) import React, { useContext } from 'react'; // old code goes here function Display() { const value = useContext(NumberContext); return <div>The answer is {value}.</div>; }
그것이 우리의 가치를 나타내기 위해 해야 할 전부입니다. 꽤 깔끔하죠? useContext()
후크를 호출하고 우리가 생성한 컨텍스트 객체를 전달하고 여기서 값을 가져옵니다.
참고: useContext 후크에 전달되는 인수는 컨텍스트 개체 자체여야 하며 useContext를 호출하는 모든 구성 요소는 컨텍스트 값이 변경될 때 항상 다시 렌더링된다는 것을 잊지 마십시오.
useReducer()
useReducer
후크는 상태의 복잡한 상태 및 전환을 처리하는 데 사용됩니다. reducer
기능과 초기 상태 입력을 받습니다. 그런 다음 배열 분해를 통해 출력으로 현재 상태와 dispatch
함수를 반환합니다.
아래 코드는 useReducer
후크를 사용하기 위한 적절한 구문입니다.
const [state, dispatch] = useReducer(reducer, initialArg, init);
useState
후크에 대한 일종의 대안입니다. 여러 하위 값과 관련된 복잡한 상태 논리가 있거나 다음 상태가 이전 상태에 종속되는 경우 일반적으로 useState
를 사용하는 것이 좋습니다.
사용 가능한 다른 React Hooks
useCallback | 이 후크는 메모화된 콜백 함수를 반환하고 종속성 트리에서 하나의 종속성이 변경되는 경우에만 변경됩니다. |
useMemo | 이 후크는 메모된 값을 반환하고 "생성" 함수와 종속성 배열을 전달할 수 있습니다. 반환되는 값은 종속성 트리의 종속성 중 하나가 변경되는 경우에만 메모된 값을 다시 사용합니다. |
useRef | 이 후크는 .current 속성이 전달된 인수( initialValue )로 초기화된 변경 가능한 ref 객체를 반환합니다. 반환된 개체는 구성 요소의 전체 수명 동안 사용할 수 있습니다. |
useImperativeHandle | 이 후크는 React에서 ref를 사용할 때 상위 구성 요소에 사용할 수 있는 인스턴스 값을 사용자 지정하는 데 사용됩니다. |
useLayoutEffect | 이 후크는 useEffect 후크와 유사하지만 모든 DOM 변형 후에 동기적으로 실행됩니다. 또한 componentDidUpdate 및 componentDidMount 와 동일한 방식으로 렌더링합니다. |
useDebugValue | 이 후크는 React Dev 도구에서 사용자 정의 후크에 대한 레이블을 표시하는 데 사용할 수 있습니다. React Dev Tools로 디버깅할 때 매우 유용합니다. |
사용자 정의 반응 후크
"custom Hook"은 이름 앞에 use
라는 단어가 붙고 다른 Hook을 호출하는 데 사용할 수 있는 JavaScript 함수입니다. 또한 구성 요소 논리를 재사용 가능한 기능으로 추출할 수 있습니다. 그것들은 내부에 다른 Hooks를 사용할 수 있는 일반적인 JavaScript 함수이며 여러 구성 요소 내에서 사용할 수 있는 공통 상태 저장 논리도 포함합니다.
아래 코드 스니펫은 무한 스크롤을 구현하기 위한 사용자 지정 React Hook의 예를 보여줍니다(Paulo Levy 작성).
import { useState } from "react"; export const useInfiniteScroll = (start = 30, pace = 10) => { const [limit, setLimit] = useState(start); window.onscroll = () => { if ( window.innerHeight + document.documentElement.scrollTop === document.documentElement.offsetHeight ) { setLimit(limit + pace); } }; return limit; };
이 사용자 정의 Hook은 start
와 pace
라는 두 개의 인수를 허용합니다. start 인수는 렌더링할 요소의 시작 수이고, pace 인수는 렌더링될 후속 요소 수입니다. 기본적으로 start
및 pace
인수는 각각 30
및 10
으로 설정됩니다. 즉, 인수 없이 실제로 Hook을 호출할 수 있으며 해당 기본값이 대신 사용됩니다.
따라서 React 앱 내에서 이 Hook을 사용하려면 '가짜' 데이터를 반환하는 온라인 API와 함께 사용합니다.
import React, { useState, useEffect } from "react"; import { useInfiniteScroll } from "./useInfiniteScroll"; const App = () => { let infiniteScroll = useInfiniteScroll(); const [tableContent, setTableContent] = useState([]); useEffect(() => { fetch("https://jsonplaceholder.typicode.com/todos/") .then(response => response.json()) .then(json => setTableContent(json)); }, []); return ( <div style={{ textAlign: "center" }}> <table> <thead> <tr> <th>User ID</th> <th>Title</th> </tr> </thead> <tbody> {tableContent.slice(0, infiniteScroll).map(content => { return ( <tr key={content.id}> <td style={{ paddingTop: "10px" }}>{content.userId}</td> <td style={{ paddingTop: "10px" }}>{content.title}</td> </tr> ); })} </tbody> </table> </div> ); }; export default App;
위의 코드는 화면에 초기 데이터 수를 표시하기 위해 무한 스크롤 후크를 사용하는 가짜 데이터( userID
및 title
) 목록을 렌더링합니다.
결론
이 튜토리얼을 통해 즐겁게 작업하셨기를 바랍니다. 항상 아래 참조에서 React Hooks에 대한 자세한 내용을 읽을 수 있습니다.
질문이 있는 경우 댓글 섹션에 남겨주시면 하나하나 답변해 드리겠습니다!
이 기사에 대한 지원 리포지토리는 Github에서 사용할 수 있습니다.
리소스 및 추가 읽을거리
- "Hooks API 참조", React.js 문서
- "React Hooks란 무엇입니까?", Robin Wieruch
- "
useContext
후크 작동 방식", Dave Ceddia - "React Hooks:
useEffect()
사용법", Hossein Ahmadi, Medium - "자신만의 맞춤형 React Hook 작성", Aayush Jaiswal, Medium
- "React Hook Recipes를 이해하기 쉬움", Gabe Ragland, useHooks()