훅(Hook)은 리액트 v16.8에서부터 도입된 기능으로, 함수혀여 컴포넌트에서 상태 및 다른 리액트 기능을 사용할 수 있게 해준다.
const [state, setState] = useState(initialState);
useState의 특징
import React, { useState } from 'react';
function ExampleComponent() {
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
function ExampleComponent() {
const [count, setCount] = useState(0);
const handleClick = () => {
// 비동기적으로 업데이트
setCount(count + 1);
setCount(count + 1);
};
return (
<div>
<p>You clicked {count} times</p>
<button onClick={handleClick}>
Click me
</button>
</div>
);
}
이 예제에서 count는 2가 아닌 1이 된다.
function ExampleComponent() {
const [count, setCount] = useState(0);
const handleIncrement = () => {
// 이전 상태를 활용하여 업데이트
setCount(prevCount => prevCount + 1);
};
return (
<div>
<p>You clicked {count} times</p>
<button onClick={handleIncrement}>
Increment
</button>
</div>
);
}
여러 상태 사용
: 컴포넌트에서 여러 개의 useState를 사용하여 여러 상태를 각각 독립적으로 관리할 수 있다.
function MultiStateComponent() {
const [count, setCount] = useState(0);
const [text, setText] = useState('');
return (
<div>
<p>Count: {count}</p>
<p>Text: {text}</p>
<button onClick={() => setCount(count + 1)}>
Increment
</button>
<input
type="text"
value={text}
onChange={(e) => setText(e.target.value)}
/>
</div>
);
}
useEffect의 특징
useEffect(() => {
// 비동기 작업 수행
const fetchData = async () => {
const result = await fetchDataFromAPI();
// 처리된 데이터를 사용하여 상태 갱신 등의 작업 수행
};
fetchData();
}, [/* 의존성 배열 */]);
useEffect(() => {
// 컴포넌트가 마운트된 후 실행되는 코드
return () => {
// 언마운트 또는 다음 useEffect 실행 전에 실행되는 정리 함수
};
}, [/* 의존성 배열 */]);
useEffect(() => {
// 특정 상태가 변경될 때만 실행되는 코드
}, [specificState]);
useEffect 사용 예시
import React, { useEffect } from 'react';
function MountedComponent() {
useEffect(() => {
// 컴포넌트가 마운트된 후 실행되는 코드
console.log('Component is mounted');
// 정리 함수 (언마운트 또는 다음 useEffect 실행 전에 실행됨)
return () => {
console.log('Component will unmount or next useEffect will run');
};
}, []); // 빈 배열은 컴포넌트가 마운트될 때 한 번만 실행됨
return <div>Mounted Component</div>;
}
import React, { useEffect, useState } from 'react';
function StateChangeEffect() {
const [count, setCount] = useState(0);
useEffect(() => {
// count 상태가 변경될 때 실행되는 코드
console.log('Count is updated:', count);
}, [count]); // count가 변경될 때마다 실행됨
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>
Increment Count
</button>
</div>
);
}
Context 란?
일반적인 React 어플리케이션데서 데이터는 props를 통해서 부모 컴포넌트에서 자식 컴포넌트로 전달된다. 어플리케이션 안의 여러 컴포넌트들에게 props로 전달해줘야하는 경우, context를 이용하면 명시적으로 props를 넘겨주지 않아도 값을 공유할 수 있게 해준다. 즉, 데이터가 필요할 때마다 props를 통해 전달할 필요 없이 context를 이용해 공유한다.
const MyContext = createContext();
컨텍스트를 사용하면, 중첩된 컴포넌트 간에 데이터를 전달하는데에 용이하며, 특히 전역적인 상태나 테마, 사용자 인증 정보같은 데이터를 효율적으로 관리할 수 있다.
useContext 의 사용법
// MyContext.js
import { createContext } from 'react';
const MyContext = createContext();
export default MyContext;
// ParentComponent.js
import React from 'react';
import MyContext from './MyContext';
function ParentComponent() {
const contextValue = 'Hello from Context!';
return (
<MyContext.Provider value={contextValue}>
{/* 자식 컴포넌트들 */}
</MyContext.Provider>
);
}
export default ParentComponent;
// ChildComponent.js
import React, { useContext } from 'react';
import MyContext from './MyContext';
function ChildComponent() {
const contextValue = useContext(MyContext);
return (
<div>
<p>{contextValue}</p>
</div>
);
}
export default ChildComponent;
useContext 사용 시 주의 사항
useRef의 주요 특징
useRef는 주로 DOM조작, 애니메이션 및 다른 Hook들과의 조합 등에서 사용된다.
useRef의 사용법
1. DOM 요소에 접근
import React, { useRef, useEffect } from 'react';
function MyComponent() {
// useRef를 사용하여 참조 생성
const myInputRef = useRef(null);
useEffect(() => {
// 컴포넌트가 마운트되면 myInputRef.current가 해당 input 요소를 참조합니다.
myInputRef.current.focus();
}, []);
return <input ref={myInputRef} />;
}
import React, { useRef, useState } from 'react';
function MyComponent() {
const renderCount = useRef(0); // 렌더링 횟수를 기록하기 위한 useRef
useEffect(() => {
renderCount.current += 1;
console.log(`Component has rendered ${renderCount.current} times.`);
});
return <div>Component content</div>;
}
useMemo
import React, { useMemo } from 'react';
function ExampleComponent({ list }) {
const total = useMemo(() => {
console.log('Calculating total...');
return list.reduce((acc, item) => acc + item, 0);
}, [list]);
return <div>Total: {total}</div>;
}
useCallback
import React, { useCallback } from 'react';
function ChildComponent({ onClick }) {
// onClick은 렌더링마다 새로운 콜백이 생성되는 것을 방지
return <button onClick={onClick}>Click me</button>;
}
function ParentComponent() {
const handleClick = useCallback(() => {
console.log('Button clicked');
}, []); // 의존성 배열이 빈 배열인 경우 항상 동일한 함수를 반환
return <ChildComponent onClick={handleClick} />;
}