기존 클래스 컴퍼넌트에서 사용하던 생명주기를 대체
리액트의 state와 생명주기 기능에 갈고리를 걸어 원하는 시점에 정해진 함수를 실행되도록 만든 것
훅의 이름은 모두 use로 시작.
클래스 컴포넌트처럼 state를 사용하고 싶으면 useState()
훅을 사용
const [변수명, set함수명] = useState(초깃값);
import React, { useState } from 'react';
function Example() {
// 새로운 state 변수를 선언하고, count라 부르겠습니다.
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
버튼이 눌렸을 때 setCount()
함수를 호출해서 카운트를 1 증가.
count의 값이 변경되면 컴포넌트가 재렌더링되면서 화면에 새로운 카운트 값이 표시.
const [fruit, setFruit] = useState('banana');
위 자바스크립트 문법은 "배열 구조 분해".
즉, useState를 사용하면 fruit라는 첫 번째 값과 setFruit라는 두 번째 값을 반환.
아래의 코드와 같은 효과를 냄.
var fruitStateVariable = useState('banana'); // 두 개의 아이템이 있는 쌍을 반환
var fruit = fruitStateVariable[0]; // 첫 번째 아이템
var setFruit = fruitStateVariable[1]; // 두 번째 아이템
useState를 이용하여 변수를 선언하면 2개의 아이템 쌍이 들어있는 배열로 만들어짐.
첫 번째 아이템은 현재 변수를 의미, 두 번째 아이템은 해당 변수를 갱신해주는 함수.
// this.setState({ fruit: 'orange' })와 같은 효과를 냅니다.
setFruit('orange');
리액트 함수 컴포넌트에서 사이드 이펙트를 실행할 수 있도록 해주는 훅
클래스 컴포넌트에서 제공하는 생명주기 함수인 componentDidMount()
componentDidupdat()
componentWillUnmount()
와 동일한 기능을 하나로 통합해서 제공.
useEffect(이펙트 함수, 의존성 배열);
첫 번째 파라미터로는 이펙트 함수가 들어가고, 두 번째 파라미터로는 의존성 배열이 들어감.
의존성 배열은 배열 안에 있는 변수 중에 하나라도 값이 변경되었을 때 이펙트 함수가 실행.
useEffect(() => {
document.title = `You clicked ${count} times`;
});
위 처럼 의존성 배열 없이 useEffect()
를 사용하면 리액트는 DOM이 변경된 이후에 해당 이펙트 함수를 실행하라는 의미
componentDidMount()
componentDidupdat()
와 동일한 역할
useEffect(() => {
ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
return () => {
ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
};
});
useEffect()에서 리턴하는 함수는 컴포넌트가 마운트 해제될 때 호출
componentWillUnmount()
와 동일한 역할
useEffect(() => {
//컴포넌트가 마운트 된 이후
//의존성 배열에 있는 변수들 중 하나라도 값이 변경되었을 때 실행됨
//의존성 배열에 빈 배열([])을 넣으면 마운트와 언마운트시에 단 한 번씩만 실행됨
//의존성 배열 생략 시 컴포넌트 업데이트 시마다 실행됨
return () => {
//컴포넌트가 마운트 해제되기 전에 실행됨
}
}, [의존성 변수1, 의존성 변수2, ...]);
의존성 배열에 들어있는 변수가 변했을 경우에만 새로 create 함수를 호출하여 결괏값 반환.
렌더링이 일어나는 동안 실행됨
const memoizedValue = useMemo(
() => {
//연산량이 높은 작업을 수행하여 결과 반환
return computeExpensiveValue(의존성 변수1, 의존성 변수2);
},[의존성 변수1, 의존성 변수2]
);
useMemo()
와 유사한 역할. 값이 아닌 함수를 반환
const memoizedCallback = useCallback(
() => {
doSomething(의존성 변수1, 의존성 변수2);
},[의존성 변수1, 의존성 변수2]
);
변경 가능한 .current라는 속성을 가진 하나의 상자
const refContainer = useRef(초깃값);
React에서 DOM 엘리먼트의 주소값이 필요할 때 사용할 수 있다.
- focus
- text selection
- media playback
- 애니메이션 적용
- d3.js, greensock 등 DOM 기반 라이브러리 활용
import { useRef } from 'react';
/* 1. 사용할 수 있도록 훅을 불러온다. */
function TextInputWithFocusButton() {
const inputEl = useRef(null);
/* 2. inputEl은 특정 엘리먼트의 주소값을 담는 변수가 된다. */
const onButtonClick = () => {
inputEl.current.focus();
/* 4. 해당 함수가 실행되면, inputEl이 가지고 있는 주소값(input)이 focus된다. */
};
return (
<>
<input ref={inputEl} type="text" />
/* 3. 특정 태그에 ref 속성을 붙이고 미리 할당했던 useRef 객체를 넣으면,
해당 태그의 주소값을 inputEl이라는 변수가 가지고 있게 된다. */
<button onClick={onButtonClick}>Focus the input</button>
</>);
}
ex) 영상 플레이/정지 등을 영상 제어하고 싶을 때
import { useRef } from "react";
export default function App() {
const videoRef = useRef(null);
/* 1. useRef를 변수에 할당하고 */
const playVideo = () => {
videoRef.current.play();
console.log(videoRef.current);
/* 3. 버튼 클릭으로 비디오 재생을 제어하거나 */
};
const pauseVideo = () => {
videoRef.current.pause();
videoRef.current.remove();
/* 4. 비디오 재생을 멈출 수도 있다. */
};
return (
<div className="App">
<div>
<button onClick={playVideo}>Play</button>
<button onClick={pauseVideo}>Pause</button>
</div>
<video ref={videoRef} width="320" height="240" controls>
/* 2. 비디오 태그의 ref 속성에 해당 변수를 할당하면 */
<source
type="video/mp4"
src="https://player.vimeo.com/external/544643152.sd.mp4?s=7dbf132a4774254dde51f4f9baabbd92f6941282&profile_id=165"
/>
</video>
</div>
);
}
훅
훅의 규칙
커스텀 훅
💻 소플의 처음만난 리액트