티스토리 뷰

반응형

React에서 컴포넌트 간의 효율적인 상태 관리는 중요한 요소 중 하나다. 특히 자식 컴포넌트에서 부모 컴포넌트의 상태를 업데이트하는 상황이 종종 있다. 자식 컴포넌트에서 부모 컴포넌트의 상태를 업데이트 여러 가지 방법이 있는데, 이러한 다양한 방법은 각각의 상황에 맞게 선택되어야 한다. 각 방법의 장단점과 코드 예시를 함께 알아보면서 효율적인 상태 관리를 구현하는 방법을 이해하도록 해보자.

 

 

1. 콜백 함수를 활용한 상태 업데이트

React의 기본 원칙 중 하나는 단방향 데이터 흐름이다. 부모 컴포넌트는 자식 컴포넌트에게 콜백 함수를 전달하고, 자식 컴포넌트에서 해당 콜백을 호출하여 부모 컴포넌트의 상태를 간접적으로 업데이트할 수 있다. 이는 단방향 데이터 프름을 유지하면서 부모 컴포넌트와 자식 컴포넌트 간의 상태 업데이트를 가능하게 한다. 주로 간단한 구조에서 사용된다.

장점

  • 간단하고 직관적인 패턴
  • React의 단방향 데이터 흐름을 유지하면서 부모 컴포넌트의 상태를 업데이트할 수 있다.

단점

  • 자식 컴포넌트가 부모 컴포넌트에 의존하므로 결합도가 높아진다.
  • 복잡한 상태 로직이나 여러 컴포넌트 간의 상태 공유에는 제한적이다.

예시 코드

// 부모 컴포넌트
import { useState } from 'react';
import ChildComponent from './ChildComponent';

const ParentComponent = () => {
  const [count, setCount] = useState(0);

  const updateCount = (newCount) => {
    setCount(newCount);
  };

  return (
    <div>
      <p>Count: {count}</p>
      <ChildComponent onUpdateCount={updateCount} />
    </div>
  );
};

// 자식 컴포넌트
import React, { useState } from 'react';

const ChildComponent = ({ onUpdateCount }) => {
  const [newCount, setNewCount] = useState(0);

  const handleClick = () => {
    onUpdateCount(newCount);
  };

  return (
    <div>
      <input
        type="number"
        value={newCount}
        onChange={(e) => setNewCount(Number(e.target.value))}
      />
      <button onClick={handleClick}>
        Update Parent Count
      </button>
    </div>
  );
};

export default ChildComponent;

 

 

 

2. Context API를 활용한 상태 관리

useContext를 사용하여 부모 컴포넌트의 상태를 전역적으로 공유하는 방법이다. Context를 통해 전역 상태를 제공하고, 자식 컴포넌트에서 해당 상태를 업데이트할 수 있다.

부모 컴포넌트에서 createContext를 사용하여 상태를 생성하고, Provider로 해당 상태를 자식 컴포넌트에 전달한다. 자식 컴포넌트는 useContext를 사용하여 해당 상태를 쉽게 사용하고 업데이트할 수 있다.

장점

  • 여러 계층의 컴포넌트 간에 편리하게 상태 전달
  • 전역적인 상태 관리가 필요한 경우 효과적

단점

  • 모든 자식 컴포넌트가 부모 컴포넌트의 상태를 필요로 할 때에만 유용

예시 코드

// 상태 관리용 Context 생성
import { createContext, useContext, useState } from 'react';

const CountContext = createContext();

export const CountProvider = ({ children }) => {
  const [count, setCount] = useState(0);

  const updateCount = (newCount) => {
    setCount(newCount);
  };

  return (
    <CountContext.Provider value={{ count, updateCount }}>
      {children}
    </CountContext.Provider>
  );
};

// 부모 컴포넌트
import { CountProvider } from './CountContext';

const App = () => {
  return (
    <CountProvider>
      {/* App 내의 자식 컴포넌트들 */}
    </CountProvider>
  );
};

// 자식 컴포넌트
import React, { useContext, useState } from 'react';
import { CountContext } from './CountContext';

const ChildComponent = () => {
  const { count, updateCount } = useContext(CountContext);

  const handleClick = () => {
    updateCount(count + 1);
  };

  return (
    <div>
      <p>Count from Context: {count}</p>
      <button onClick={handleClick}>
        Update Count from Context
      </button>
    </div>
  );
};

export default ChildComponent;

 

 

 

3. useReducer를 활용한 상태 업데이트

useReducer 훅을 사용하여 복잡한 상태 로직을 다루는 방법이다. useReducer를 사용하면 복잡한 상태 로직을 다루기에 용이하며, 여러 액션을 통해 상태를 업데이트할 수 있다. 부모 컴포넌트에서 useReducer를 사용하여 상태와 액션을 관리한다. 자식 컴포넌트에 diaspatch 함수를 전달하면 자식 컴포넌트에서 dispatch를 통해 부모 컴포넌트의 상태를 간접적으로 업데이트할 수 있다.

장점

  • 복잡한 상태 로직을 다루기에 용이
  • 여러 액션을 통한 상태 업데이트가 가능

단점

  • 작은 규모의 애플리케이션에서는 useReducer 사용이 오버헤드일 수 있다.

예시 코드

// 부모 컴포넌트
import { useReducer } from 'react';
import ChildComponent from './ChildComponent';

const initialState = { count: 0 };

const reducer = (state, action) => {
  switch (action.type) {
    case 'INCREMENT':
      return { count: state.count + 1 };
    default:
      return state;
  }
};

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

  return (
    <div>
      <p>Count: {state.count}</p>
      <ChildComponent dispatch={dispatch} />
    </div>
  );
};

// 자식 컴포넌트
import React from 'react';

const ChildComponent = ({ dispatch }) => {
  return (
    <button onClick={() => dispatch({ type: 'INCREMENT' })}>
      Increment
    </button>
  );
};

export default ChildComponent;

 

 

4. Redux를 이용한 상태 관리

Redux는 전역 상태 관리 라이브러리로, 상태를 중앙에서 효율적으로 관리한다. 부모 컴포넌트에서 Redux 스토어를 생성하고, 자식 컴포넌트에서 Redux 액션을 디스패치하여 부모 컴포넌트의 상태를 업데이트할 수 있다.

장점

  • 부모 컴포넌트의 상태를 직접 업데이트하는 대신, Redux를 통해 자식 컴포넌트가 간접적으로 부모 컴포넌트와 통신할 수 있다.

단점

  • 작은 규모의 애플리케이션에서는 Redux 사용이 오버헤드일 수 있다.

예시 코드

1) Redux 설정

// actions.js
export const increment = () => ({
  type: 'INCREMENT',
});

// reducer.js
const initialState = {
  count: 0,
};

const reducer = (state = initialState, action) => {
  switch (action.type) {
    case 'INCREMENT':
      return { ...state, count: state.count + 1 };
    default:
      return state;
  }
};

export default reducer;

// store.js
import { createStore } from 'redux';
import reducer from './reducer';

const store = createStore(reducer);

export default store;

 

2) 부모 컴포넌트에서 Redux store 사용

부모 컴포넌트에서 Redux store를 생성하고 상태를 업데이트할 액션을 디스패치한다.

// ParentComponent.js
import React from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { increment } from './actions';

const ParentComponent = () => {
  const count = useSelector((state) => state.count);
  const dispatch = useDispatch();

  const handleIncrement = () => {
    dispatch(increment());
  };

  return (
    <div>
      <p>Count: {count}</p>
      <ChildComponent onIncrement={handleIncrement} />
    </div>
  );
};

 

3) 자식 컴포넌트에서 action dispatch

자식 컴포넌트에서 부모 컴포넌트의 상태를 업데이트하기 위해 action을 dispatch 한다.

// ChildComponent.js
import React from 'react';

const ChildComponent = ({ onIncrement }) => {
  return (
    <div>
      <button onClick={onIncrement}>Increment in Parent</button>
    </div>
  );
};

export default ChildComponent;

 

 

반응형
반응형
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31