다양한 훅 함수
useEffect
렌더링이 끝난 뒤에 실행돼야 하는 작업
useEffect(이펙트 함수, 의존성 배열);
의존성 배열의 값이 하나라도 변경되면 useEffect 함수가 실행된다.
useEffect함수는 처음 컴포넌트가 렌더링 된 이후와 업데이트로 인한 재렌더링 이후에 실행된다.
useEffect함수가 mount, unmount 시에 단 한 번씩만 실행되게 할 때
useEffect(이펙트 함수, []);
빈배열인 경우 어떠한 값에도 의존하지 않기 때문에 시작과 종료시에만 실행된다.
의존성 배열을 생략하면 컴포넌트가 업데이트될 때마다 호출 됨
useEffect(이팩트 함수);
버튼 클릭 할 때마다 타이틀 제목바뀌는 소스
생략 – 컴포넌트가 업데이트 될 때마다 실행
import React, {useState, useEffect} from "react";
function Counter(props) {
const [count, setCount] = useState(0);
useEffect(()=>{
document.title = `클릭 횟수: ${count}`;
});
return (
<div>
<button onClick={()=>setCount(count+1)}>클릭</button>
</div>
)
}
export default Counter;
빈 배열 - mount와 unmount 될 때 한 번씩만 실행
import React, {useState, useEffect} from "react";
function Counter(props) {
const [count, setCount] = useState(0);
useEffect(()=>{
document.title = `클릭 횟수: ${count}`;
},[]);
return (
<div>
<button onClick={()=>setCount(count+1)}>클릭</button>
</div>
)
}
export default Counter;
배열 - 변수들 중 하나라도 값이 변경되었을 때 실행
import React, {useState, useEffect} from "react";
function Counter(props) {
const [count, setCount] = useState(0);
useEffect(()=>{
document.title = `클릭 횟수: ${count}`;
}, [count]);
return (
<div>
<button onClick={()=>setCount(count+1)}>클릭</button>
</div>
)
}
export default Counter;
1초 마다 자동 증감 카운트
import React, {useState, useEffect} from "react";
function Counter(props) {
const [count, setCount] = useState(0);
const [isRunning, setIsRunning] = useState(false);
useEffect(()=>{
if(isRunning) {
setTimeout(()=> setCount(count+1), 1000);
}
},[count, isRunning]);
return (
<div>
<p>{count}</p>
<p>{count % 2 == 0 ? '짝수' : "홀수"}</p>
<button onClick={()=>setIsRunning(!isRunning)}>{isRunning ? '정지' : '시작'}</button>
</div>
)
}
export default Counter;
useMemo
Memoized value를 리턴하는 훅
Memoization: 컴퓨터가 동일한 계산을 반복해야 할 때, 이전에 계산한 값을 메모리에 저장함으로써 동일한 계산의 반복을 수행을 제거하여 프로그램 실행 속도를 빠르게 하는 기술-> 성능 최적화
메모이제이션이 된 결과값이 Memoized value
useMemo 훅이 필요한 경우
계산량이 많은 작업의 경우 컴포넌트가 랜더링될 때마다 수행하면 UI 지연 발생
만약 함수의 x,y 인자값이 같은 경우 매번 다시 계산할 필요가 없음
const memoValue = useMemo(
() => {
// 연산량이 높은 작업을 수행하여 결과를 반환
return
},
[의존성 변수1, 의존성 변수2]
);
의존성 배열 값이 변경될 때만 콜백 함수를 호출
useMemo()로 전달된 함수는 렌더링이 일어나는 동안 실행됨
렌더링이 일어나는 동안 실행되서는 안되는 작업(useEffect)은 useMemo()에 사용하면 안됨
첫 번째 인자의 값을 리턴해야 함
useMemo() – 의존성 배열 생략
const memoValue = (()=>실행코드);
의존성 배열을 넣지 않을 경우, 매 렌더링마다 함수가 실행되므로 의미가 없음
의존성 배열이 빈 배열일 경우, 컴포넌트 마운트 시에만 값을 계산
const memoValue = (()=> return 실행코드, []);
useCallback
함수를 메모이제이션 하기 위한 훅
useMemo() Hook과 유사하지만 값이 아닌 함수를 반환
useMemo와 다르게 함수자체를 반환하는 개념이기 때문에 함수 내부 리턴값은 useCallback의 동작에 영향을 주지 않는다.
const memoizedCallback = useCallback(
() => {
do(의존성 변수1, 의존성 변수2);
}, [의존성 변수1, 의존성 변수2]
)
useCallback() 훅을 사용하지 않고 컴포넌트 내에 함수를 정의할 경우, 렌더링이 일어날 때마다 함수가 새로 정의됨
import React, {useState, useCallback , useEffect} from "react";
function Counter(props) {
// 상태 변수: 검색어(keyword)와 검색 결과(data)
const [keyword, setKeyword] = useState("");
const [data, setData] = useState("");
const fetchData = useCallback(()=>{
setTimeout(()=>{
setData(`"${keyword}"에 대한 검색 결과`);
}, 1000);
}, [keyword]);
useEffect(()=>{
if(keyword) fetchData(); // keyword가 비어있지 않으면 fetchData 호출
},[fetchData]); // fetchData가 변경될 때만 effect 실행);
return (
<div>
<h2>검색 예제 (단일 컴포넌트)</h2>
<input
type="text"
placeholder="검색어 입력"
value={keyword}
onChange={(e) => setKeyword(e.target.value)} // 입력값 변경 시 keyword 상태 업데이트
/>
<p>결과: {data}</p> {/* 검색 결과 표시 */}
<button onClick={fetchData}>수동 검색</button> {/* 버튼 클릭 시 수동으로 fetchData 호출 */}
</div>
);
}
export default Counter;
useCallback, useMemo 차이점
useRef
Reference를 사용하기 위한 훅
리액트 레퍼런스: 특정 컴포넌트에 접근할 수 있는 객체
useRef() 반환값 { current: 초기값 } 형태의 객체
import React, { useState, useRef } from 'react';
function Test(props) {
// useRef 훅을 사용하여 input 요소를 참조할 객체 생성
// 초기값은 null이며, 실제 DOM 요소가 할당됨
const inputElem = useRef(null);
// 버튼 클릭 시 호출되는 함수
const onButtonClick = () => {
// inputElem.current는 실제 input DOM 요소를 가리킴
// 해당 요소에 focus() 함수를 호출하여 포커스를 맞춤
inputElem.current.focus();
};
// 입력 비활성화 설정(true/false)
const d = ()=>{
inputElem.current.disabled = true;
}
return (
<div>
{/*
ref 속성으로 inputElem을 연결하여
inputElem.current에 이 DOM 요소가 할당됨 */}
<input ref={inputElem}></input>
{/* 버튼 클릭 시 onButtonClick 함수 실행 */}
<button onClick={onButtonClick}>
Focus
</button>
<button onClick={d}>
disabled
</button>
</div>
);
}
export default Test;