본문 바로가기
React-study/presentation

[발표] useReducer / useContext / useRef

by 어느새벽 2024. 5. 30.

useReducer

상태 관리를 위해 사용하는 훅 중 하나로 상태가 복잡하거나 상태 변화 로직이 여러가지로 나뉠 때 유용함.

  • 상태(state): 컴포넌트의 현재 상태. 어떤 값이나 객체일 수 있음
  • reducer: 상태와 액션을 받아 새로운 상태를 반환하는 함수이다. 
  • 액션 : 상태를 어떻게 변경할지를 설명하는 객체이다. 일반적으로 type 속성을 가집니다. 예: { type: 'increment' }

useReducer를 사용하기 위해서는 다음 세 가지가 필요하다.

  • 초기 상태 (initial state)
  • 리듀서 함수 (reducer function)
  • 디스패치 함수 (dispatch function)

 

import React, { useReducer } from 'react';

// 초기 상태 정의
const initialState = { count: 0 };

// 리듀서 함수 정의
function 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 훅 사용
  const [state, dispatch] = useReducer(reducer, initialState);

  return (
    <div>
      <p>Count: {state.count}</p>
      <button onClick={() => dispatch({ type: 'increment' })}>+</button>
      <button onClick={() => dispatch({ type: 'decrement' })}>-</button>
    </div>
  );
}

export default Counter;

 

 

const [state, dispatch] = useReducer(reducer, initialState);

 

  • state는 우리가 변화를 줄 상태이다.
  • initialState는 위에 우리가 지정해준 값이다. count : 0으로 현재 state가 된다.
  • reducer는 state의 상태를 변화해줄 함수이다.
  • dispatch는 액션 객체를 reducer함수로 보내는 함수이다. 

*dispatch 쉽게 이해하기

-  dispatch 뜻이 '파견하다, 보내다'로 함수안의 여러 타입 중 하나를 가져와 보낸다는 느낌으로 생각하면 됨!

-  useState의 setSomething 자리와 동일하니 setSomething 대신 사용한다고 생각하면 쉬움

 

 

useContext 

useContext는 리액트에서 제공하는 훅 중 하나로 컴포넌트들을 전역적인 데이터에 쉽게 접근 할 수 있도록 해준다.

 

useContext를 사용하기 위해 필요한 세가지

  • Context 생성 
  • Provider 설정
  • useContext  사용

 

import React, { createContext, useState, useContext } from 'react';

// 1. Context 생성
const ThemeContext = createContext();

// 2. Provider 설정
function ThemeProvider({ children }) {
  const [theme, setTheme] = useState('light');

  return (
    <ThemeContext.Provider value={{ theme, setTheme }}>
      {children}
    </ThemeContext.Provider>
  );
}

// 3. useContext 사용
function ThemedComponent() {
  const { theme, setTheme } = useContext(ThemeContext);

  return (
    <div style={{ background: theme === 'light' ? '#fff' : '#333', color: theme === 'light' ? '#000' : '#fff' }}>
      <p>The current theme is {theme}</p>
      <button onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}>Toggle Theme</button>
    </div>
  );
}

// 애플리케이션 루트
function App() {
  return (
    <ThemeProvider>
      <ThemedComponent />
    </ThemeProvider>
  );
}

export default App;

 

useRef

useRef는 리액트에서 제공하는 훅으로 두가지 주요 용도로 사용된다. 

DOM 요소 접근과 값 유지이다.

useRef를 사용면 컴포넌트 내의 특정 DOM 요소에 직접 접근할 수 있다.

예를 들어, 입력 필드에 자동으로 포커스를 주고 싶을 때 사용할 수 있다.

 

1.DOM 요소 접근

import React, { useRef, useEffect } from 'react';

function TextInput() {
  const inputRef = useRef(null);  // inputRef는 DOM 요소를 참조할 변수

  useEffect(() => {
    inputRef.current.focus();  // 컴포넌트가 렌더링된 후 input 요소에 포커스를 준다
  }, []);

  return <input ref={inputRef} type="text" />;
}

export default TextInput;

 

위 코드에서 inputRef는 useRef(null)로 초기화된다. 그런 다음 input요소의 ref 속성에 inputRef를 할당한다.

useEffect 훅을 사용하여 컴포넌트가 처음 렌더링될 때 inputRef.current.focus()를 호출하여 입력 필드에 포커스를 준다.

 

2. 값 유지

useRef는 리렌더링 간에 값을 유지하는 데 사용할 수도 있다. 상태(state)와 달리, useRef로 저장된 값이 변경되어도 컴포넌트가 다시 렌더링 되지 않는다.

import React, { useRef, useState } from 'react';

function Counter() {
  const countRef = useRef(0);  // countRef는 카운트를 저장할 변수
  const [renderCount, setRenderCount] = useState(0);  // 컴포넌트를 리렌더링하기 위한 상태

  const increment = () => {
    countRef.current++;  // countRef의 값을 증가시킨다
    console.log('Count:', countRef.current);
  };

  const forceUpdate = () => {
    setRenderCount(renderCount + 1);  // 상태를 변경하여 리렌더링을 강제한다
  };

  return (
    <div>
      <p>Count: {countRef.current}</p>
      <button onClick={increment}>Increment</button>
      <button onClick={forceUpdate}>Force Update</button>
    </div>
  );
}

export default Counter;

 

countRef는 useRef(0)로 초기화되어 값이 0으로 설정된다. increment 함수는 countRef.current 값을 증가 시키지만 이는 컴포넌트를 다시 렌더링하지 않습니다. forceUpdate 함수는 setRenderCount를 사용하여 상태를 업데이트하고 컴포넌트를 강제로 다시 렌더링한다.