[React다루는기술] 10. React Hook
in React on React 다루는 기술
React Hook
은 함수 컴포넌트에서 상태(state) 및 생명주기 기능을 사용할 수 있게 해주는 기능입니다. 훅은 함수 컴포넌트에서 상태 관리나 부수 효과(side effect) 등을 더 쉽게 다룰 수 있도록 도와줍니다. 리액트 훅은 함수형 컴포넌트에서만 사용할 수 있습니다.
1. useState
useState
는 React에서 상태를 관리할 수 있게 해주는 훅(Hook) 중 하나입니다. 함수형 컴포넌트에서 상태를 사용할 수 있게 도와주며, 클래스 컴포넌트에서의 this.state와 유사한 기능을 제공합니다.
useState를 사용하려면 React에서 제공하는 useState 함수를 가져와야 합니다. 다음은 간단한 사용 예제입니다.
import React, { useState } from 'react';
function ExUseState() {
// useState 훅을 사용하여 상태를 정의합니다.
// count는 현재의 상태 값, setCount는 상태를 갱신하는 함수입니다.
const [count, setCount] = useState(0);
return (
<div>
<p>Count: {count}</p>
{/* 버튼 클릭 시 setCount 함수를 사용하여 count 값을 갱신합니다. */}
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}
export default ExUseState;
2. useEffect
useEffect
는 React 함수형 컴포넌트에서 부수 효과(side effect)를 다루기 위한 훅(Hook) 중 하나입니다. 부수 효과란 컴포넌트 외부의 상태를 변경하거나, 데이터를 가져오는 등의 작업을 의미합니다. useEffect를 사용하면 컴포넌트의 렌더링 이후에 특정 작업을 수행할 수 있다.
useEffect는 두번째 파라미터 배열에 무엇을 넣는지에 따라 실행되는 조건이 달라진다. 컴포넌트가 언마운트되기 전이나 업데이트되기 직전에 어떠한 수행하고 싶다면 useEffect에서 cleanup함수
를 반환해줘야 합니다.
import React, { useEffect } from 'react';
function ExUseEffect() {
useEffect(() => {
// 이곳에 부수 효과를 수행하는 코드를 작성합니다.
console.log('Component is mounted!');
// 컴포넌트가 언마운트되기 전에 정리(clean-up) 작업을 수행할 경우
return () => {
console.log('Component will unmount!');
// 정리(clean-up) 코드 작성
};
}, []); // 두 번째 매개변수로 전달된 배열에 따라 언제 useEffect를 실행할지 결정됩니다.
return (
<div>
<p>Component content goes here.</p>
</div>
);
}
export default ExUseEffect;
useEffect를 사용하면 컴포넌트 라이프사이클의 componentDidMount
, componentDidUpdate
, componentWillUnmount와 유사한 동작을 수행할 수 있습니다. 함수 컴포넌트에서 부수 효과를 다루는 데 유용하게 사용됩니다.
마운트 시에만 실행
useEffect(() => {
console.log('Component is mounted!');
}, []);
특정 상태 값이 변경될 때만 실행
const [count, setCount] = useState(0);
useEffect(() => {
console.log('Count has changed:', count);
}, [count]);
마운트 및 언마운트 시에 실행 및 정리 작업
useEffect(() => {
console.log('Component is mounted!');
return () => {
console.log('Component will unmount!');
// 정리(clean-up) 코드 작성
};
}, []);
3. useReducer
reducer는 현재 상태, 그리고 업데이트를 위해 필요한 정보를 담은 액션(action) 값을 전달받아 새로운 상태를 반환하는 함수이다. 새로운 상태를 주는 것은 불변성이다.
useReducer
는 일반적으로 복잡한 상태 로직이나 여러 액션이 발생할 때 사용됩니다. 또한, useReducer는 useState로 대체 가능하지만, 코드를 더 구조적으로 유지하거나 상태 로직을 컴포넌트 외부로 분리할 때 유용하다.
import React, { useReducer } from 'react';
// reducer 함수
const reducer = (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(reducer, { 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;
reducer 함수 :
- reducer 함수는 현재 상태(state)와 액션(action)을 받아 새로운 상태를 반환하는 함수입니다.
- 액션은 상태를 어떻게 업데이트할지에 대한 정보를 포함하고 있습니다.
- reducer 함수는 switch 문이나 if-else 문을 사용하여 각 액션에 대한 업데이트 로직을 정의합니다.
dispatch 함수 :
- dispatch 함수는 reducer 함수를 호출하여 상태를 업데이트하는 역할을 합니다.
- 컴포넌트에서 dispatch 함수를 호출하면 reducer 함수가 실행되어 상태가 갱신됩니다.
4. useMemo
useMemo
는 React의 훅 중 하나로, 계산 비용이 많이 드는 함수나 연산의 결과를 메모이제이션하여 성능을 최적화하는 데 사용됩니다. 특히 렌더링이 불필요하게 반복되는 경우에 유용하다.
useMemo Hook을 사용하면 list값이 변경되어야 만 getAverage 를 호출해서 평균을 계산한다.
그레서 input값이 변경된다고 계산하지 않는다.
import { useState, useMemo } from "react";
const getAverage = (numbers) => {
if (numbers.length === 0) return 0;
const sum = numbers.reduce((a, b) => a + b);
return sum / numbers.length;
};
const ExUseMemo = () => {
const [list, setList] = useState([]);
const [number, setNumber] = useState("");
const onChange = (e) => {
setNumber(e.target.value);
};
const onInsert = () => {
const nextList = list.concat(parseInt(number));
setList(nextList);
setNumber("");
};
//useMemo Hook을 사용하면 list값이 변경되어야 만 getAverage 를 호출해서 평균을 계산한다.
//그레서 input값이 변경된다고 계산하지 않는다.
const avg = useMemo(() => getAverage(list), [list]);
return (
<div>
<input value={number} onChange={onChange} />
<button onClick={onInsert}>등록</button>
<ul>
{list.map((value, index) => (
<li key={index}>{value}</li>
))}
</ul>
<p>* 평균값:{avg}</p>
</div>
);
};
export default ExUseMemo;
useCallback
useCallback의 의존성 배열에 여러 개의 값이 포함되어 있는 경우, 해당 값들 중 하나라도 변경되었을 때에만 함수가 다시 생성되고, 그렇지 않으면 메모이제이션된 함수가 재사용된다.
import React, { useState, useCallback } from 'react';
const ParentComponent = () => {
const [countA, setCountA] = useState(0);
const [countB, setCountB] = useState(0);
// countA나 countB가 변경될 때에만 함수가 다시 생성
const handleButtonClick = useCallback(() => {
console.log('Button Clicked!');
// 여기에 처리 로직 추가
}, [countA, countB]);
return (
<div>
<p>Count A: {countA}</p>
<button onClick={() => setCountA(countA + 1)}>Increment A</button>
<p>Count B: {countB}</p>
<button onClick={() => setCountB(countB + 1)}>Increment B</button>
<button onClick={handleButtonClick}>Handle Click</button>
</div>
);
};
const App = () => {
return (
<div>
<ParentComponent />
</div>
);
};
export default App;
useRef
useRef는 React에서 참조(reference)를 다루는 훅 중 하나로, 주로 DOM 요소에 직접 접근하거나 함수 컴포넌트 내에서 변수를 유지하는 용도로 사용된다.
import React, { useRef, useEffect } from "react";
const ExUseRef = () => {
const inputRef = useRef(null);
useEffect(() => {
// 마운트 시에 input 요소에 포커스를 주기 위해 useRef로 얻은 ref를 사용
inputRef.current.focus();
}, []);
const handleButtonClick = () => {
// 버튼 클릭 시 input 요소에 다시 포커스를 주기
inputRef.current.focus();
};
return (
<div>
<input type="text" ref={inputRef} />
<button onClick={handleButtonClick}>Focus Input</button>
</div>
);
};
export default ExUseRef;