use키워드를 붙여서 클래스형 컴포넌트들이 가지고 있는 기능들을 함수형 컴포넌트가 낚아채서 사용할 수 있게 하는 기능이다.(ex. useState, useEffect, useRef...)
클래스형 컴포넌트의 길어지는 코드 길이 문제 , 중복 코드, 가독성 문제 등등을 해결하기 위해 등장했다.
useState를 사용하면 컴포넌트의 상태를 생성하고, 해당 상태 값을 변경할 수 있는 함수를 제공한다. 이 함수를 호출하면 상태가 업데이트되고, 컴포넌트가 자동으로 다시 렌더링된다.
import React, { useState } from 'react';
function Counter() {
// 초기 상태값인 count를 0으로 설정하고, 상태 업데이트 함수 setCount를 얻습니다.
const [count, setCount] = useState(0);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
<button onClick={() => setCount(count - 1)}>Decrement</button>
</div>
);
}
export default Counter;
컴포넌트의 라이프사이클 이벤트와 비슷한 역할을 하는 Hook이다. 컴포넌트가 마운트, 업데이트, 언마운트될 때 원하는 동작을 수행할 수 있게 해준다.
import React, {useEffect} from "react";
// 1. 리액트로부터 불러온다
useEffect(()=>{
// 2. todo... => 콜백함수 작성
},[])
// 3. []의존성 배열 작성 , 이 배열 내에 값이 변화하면 콜백함수가 수행된다
=> 실행 시 앱의 변경사항이 생길때마다 render가 되기 때문에 콜백 함수가 반복적으로 호출될 수 있다. 이 때 의존성 배열을 비워 두면 한번만 실행된다.
값을 메모이제이션하여 성능 최적화에 활용하는 Hook이다 계산 비용이 높은 연산 결과를 캐싱하여 재계산을 줄일 수 있다.
=> 이 말이 어려웠는데 같은 입력에 대해 항상 동일한 출력이 생성되는 함수의 경우, useMemo를 사용하여 이전에 계산한 결과를 캐시하면 중복 계산을 피할 수 있고 리랜더링을 줄인다.
=> 연산 호출을 최적화 한다. 이렇게 이해하니 좀 나은거 같다.
Memoization(메모이제이션)
이미 계산 해 본 연산 결과를 기억 해 두었다가 동일한 계산을 시키면 , 다시 연산하지 않고 기억해 두었던 데이터를 반환 시키게 하는 방법
import React, { useMemo, useState } from 'react';
function ExpensiveComponent() {
const [count, setCount] = useState(0);
const calculateExpensiveValue = useMemo(() => {
console.log('Calculating expensive value...');
// 복잡한 계산을 수행하는 함수
return count * 2;
}, [count]);
//배열에 나열된 값이 변할 때만 함수를 다시 실행하고, 그렇지 않으면 이전에 계산한 값을 재사용한다.
return (
<div>
<p>Count: {count}</p>
<p>Expensive Value: {calculateExpensiveValue}</p>
<button onClick={() => setCount(count + 1)}>Increment Count</button>
</div>
);
}
usememo가 함수의 결과값을 반환 즉 값 자체를 메모이제이션하는데 usecallback은 주로 함수를 메모이제이션 하여 자식 컴포넌트로 전달할 때 함수 재생성을 방지하는데 사용한다.
import React, { useState, useCallback } from 'react';
function Button({ onClick, children }) {
console.log('Button rendered');
return <button onClick={onClick}>{children}</button>;
}
function App() {
const [count, setCount] = useState(0);
// useCallback을 사용하여 클릭 이벤트 핸들러를 메모이제이션
const handleClick = useCallback(() => {
setCount(count + 1);
}, [count]);
return (
<div>
<h1>Counter App</h1>
<p>Count: {count}</p>
<Button onClick={handleClick}>Increment Count</Button>
</div>
);
}
export default App;
=>useCallback을 사용하여 클릭 이벤트 핸들러를 메모이제이션하여 컴포넌트의 렌더링이 발생할 때마다 새로운 함수가 생성되지 않도록 한다.
DOM 요소나 컴포넌트의 상태를 저장하고 관리하는 데 사용된다.useRef를 사용하면 컴포넌트의 렌더링과 관련없이 값을 저장하고 접근할 수 있다.
import React, { useRef } from 'react';
function FocusInput() {
const inputRef = useRef(null);
const handleButtonClick = () => {
inputRef.current.focus();
};
return (
<div>
<input ref={inputRef} type="text" />
<button onClick={handleButtonClick}>Focus Input</button>
</div>
);
}
export default FocusInput;
복잡한 상태 관리를 위해 사용되는 기능이다.
//기본 구문
const [state, dispatch] = useReducer(reducer, initialState);
state
현재 상태 값을 나타내는 변수
dispatch
액션을 발생시켜 상태 변화를 요청하는 함수
reducer
상태 변화를 처리하는 함수. 이 함수는 현재 상태와 액션을 받아 다음 상태를 반환한다.
initialState
컴포넌트가 처음 렌더링될 때 초기 상태 값
import React, { useReducer } from 'react';
// 상태 변화를 처리하는 reducer 함수
function counterReducer(state, action) {
switch (action.type) {
case 'INCREMENT':
return { count: state.count + 1 };
case 'DECREMENT':
return { count: state.count - 1 };
default:
return state;
}
}
function Counter() {
// useReducer를 사용하여 상태와 dispatch 함수를 얻습니다.
const [state, dispatch] = useReducer(counterReducer, { count: 0 });
return (
<div>
<p>Count: {state.count}</p>
<button onClick={() => dispatch({ type: 'INCREMENT' })}>Increment</button>
<button onClick={() => dispatch({ type: 'DECREMENT' })}>Decrement</button>
</div>
);
}
export default Counter;
여담... 리액트 공식 문서를 보면 아래와 같이 써있다...
매우 감사하다