Search
Duplicate
📒

[React 완벽 가이드] 04-2. useReducer, useMemo, useRef

상태
수정중
수업
React 완벽 가이드
주제
연관 노트
3 more properties
참고

React Hook 2

useReducer

NOTE
useReducer는 컴포넌트에 리듀서를 추가할 수 있는 Hook이다!
import { useReducer } from 'react'; function reducer(state, action) { // reducer함수(type에 따라 동작시키는 함수) if (action.type === 'incremented_age') { return { age: state.age + 1 }; } throw Error('Unknown action.'); } export default function Counter() { // 컴포넌트(버튼에 따라 값이 변경) // [state, dispatch] = useReducer(reducer, initialState, init); const [state, dispatch] = useReducer(reducer, { age: 42 }); // dispatch를 통해서 type을 변경한다. return ( <> <button onClick={() => { dispatch({ type: 'incremented_age' }) }}> Increment age </button> <p>Hello! You are {state.age}.</p> </> ); }
JavaScript
복사
state
컴포넌트에서 사용할 상태
dispatch
1번째 인자인 reducer 함수를 실행시킨다
컴포넌트 내에서 state의 업데이트를 위해 사용된다.
rudecer
컴포넌트 외부에서 state를 업데이트 하는 함수
현재 state, action 객체를 인자로 받아, 기존의 state를 대체하여 새로운 state를 만들어 낸다
initialState
초기 state
init
초기 함수 (state를 조금 지연해서 생성하기 위해 사용)

useState와 useReducer

useState는 주요 state 관리도구이며, 개별 state나 독립적인 간단한 state관리에 적합하다.
useReducer는 복잡한 로직을 컴포넌트 함수 밖으로 이동시킬 수 있으며, 연관된 state 데이터 관리에 적합하다.

useMemo

useMemo는 비용이 많이 드는 계산 결과를 캐시할 수 있는 Hook이다!
import { useMemo } from 'react'; function TodoList({ todos, tab }) { // 재렌더링 간 계산 결과를 캐시한다. const visibleTodos = useMemo( () => filterTodos(todos, tab), [todos, tab] ); // ... }
JavaScript
복사
React는 Virtual DOM을 통해서 변경된 부분만 효율적으로 업데이트를 해준다.
그런데 React는 Tree구조로 되어있고, 최상위 컴포넌트에서 아주 사소한 변화가 일어나더라도, 아래의 모든 컴포넌트들을 모두 재평가해야 하는가?
실제로 이러한 과정은 성능차이를 일으키며, 특정 상황에서 컴포넌트가 재실행하지 않는 방법을 도입했다!
비슷한 함수로 useCallback이 존재한다.

useRef

NOTE
useRef는 DOM 요소나 컴포넌트의 인스턴스에 접근하거나 값의 참조를 유지할 수 있습니다.

1. DOM 요소에 접근

function FocusInput() { const inputRef = useRef(null); const focusInput = () => { inputRef.current.focus(); // input 요소에 포커스 }; return ( <div> {/* ref를 통해서 참조값 설정 */} <input ref={inputRef} type="text" /> <button onClick={focusInput}>포커스 주기</button> </div> ); } export default FocusInput;
JavaScript
복사
Dom 요소 접근 1
interface NtcMttrUserDetailFormProps { data: NtcMttrUserResponse; } const NtcMttrUserDetailForm = ({ data }: NtcMttrUserDetailFormProps) => { // useRef의 타입을 HTMLTextAreaElement 또는 null로 지정 const textareaRef = useRef<HTMLTextAreaElement | null>(null); useEffect(() => { const textarea = textareaRef.current; if (textarea) { // 높이를 자동으로 초기화 & 실제 스크롤 높이로 높이 설정 textarea.style.height = 'auto'; textarea.style.height = `${textarea.scrollHeight + 40}px`; } }, [data.pstCn]); // data.pstCn이 변경될 때마다 높이 조절 return ( <Box mb="4" pointerEvents={'auto'} height={'100%'}> <Box mb={'2'}> <Text fontSize="xl" as="b"> 공지사항 내용 </Text> </Box> <Flex gap="4" direction="column" height={'100%'}> <DetailField label="제목" value={data.pstTtl}></DetailField> <Textarea ref={textareaRef} value={data.pstCn} isReadOnly sx={{ minHeight: '500px', }} /> </Flex> </Box> ); };
TypeScript
복사
Dom 요소 접근 2

2. 값의 참조 유지하기

useRef()를 사용하여 컴포넌트가 리렌더링되어도 값이 유지되도록 할 수 있습니다. 이 값은 컴포넌트가 리렌더링 되어도 변하지 않습니다.
function Counter() { const [count, setCount] = useState(0); const countRef = useRef(0); const increment = () => { setCount(count + 1); countRef.current++; // count 값 보존 }; const showAlert = () => { alert(`countRef 값: ${countRef.current}`); }; return ( <div> <p>State Count: {count}</p> <p>Ref Count: {countRef.current}</p> <button onClick={increment}>증가</button> <button onClick={showAlert}>Alert Ref Count</button> </div> ); } export default Counter;
TypeScript
복사