본문 바로가기
React

React에서 컴포넌트 간 데이터 전달하기

by 굿센스굿 2024. 12. 11.
반응형

 

React 애플리케이션을 개발할 때 컴포넌트 간 데이터를 전달하는 것은 매우 중요한 주제입니다. 특히 React는 단방향 데이터 흐름(one-way data flow)을 기본으로 하기 때문에, 데이터가 부모에서 자식 컴포넌트로 흐르는 방식과, 때로는 형제 컴포넌트 간 또는 자식에서 부모로 데이터를 전달하는 방식을 이해하는 것이 필수적입니다. 이번 블로그에서는 React에서 컴포넌트 간 데이터를 전달하는 다양한 방법을 상세히 알아보겠습니다.


1. 부모에서 자식으로 데이터 전달하기 (Props)

Props는 React에서 가장 기본적인 데이터 전달 방법입니다. 부모 컴포넌트는 자식 컴포넌트에 데이터를 전달하기 위해 props를 사용합니다. Props는 읽기 전용으로, 자식 컴포넌트는 전달받은 데이터를 수정할 수 없습니다.

코드 예제

function ParentComponent() {
  const message = "React is awesome!";
  return <ChildComponent message={message} />;
}

function ChildComponent({ message }) {
  return <p>{message}</p>;
}

위 예제에서 ParentComponent는 문자열 데이터를 ChildComponent에 전달하고, 자식 컴포넌트는 이를 출력합니다.

장점

  • 간단하고 직관적입니다.
  • 데이터 흐름이 명확합니다.

단점

  • 컴포넌트 계층이 깊어지면 Prop Drilling 문제가 발생할 수 있습니다.

2. 자식에서 부모로 데이터 전달하기 (Callback Props)

React는 단방향 데이터 흐름을 따르기 때문에 자식 컴포넌트에서 부모로 데이터를 전달하려면 부모가 콜백 함수를 props로 전달해야 합니다. 자식은 이 함수를 호출하면서 데이터를 부모에게 전달할 수 있습니다.

코드 예제

function ParentComponent() {
  const handleData = (data) => {
    console.log("Received from child:", data);
  };

  return <ChildComponent onSendData={handleData} />;
}

function ChildComponent({ onSendData }) {
  const sendDataToParent = () => {
    onSendData("Hello, Parent!");
  };

  return <button onClick={sendDataToParent}>Send Data</button>;
}

이 예제에서 자식 컴포넌트는 부모에게 데이터를 전달하기 위해 버튼 클릭 이벤트에서 onSendData를 호출합니다.

장점

  • 부모가 자식으로부터 데이터를 명시적으로 받을 수 있습니다.

단점

  • 복잡한 계층 구조에서는 관리가 어려울 수 있습니다.

3. 형제 컴포넌트 간 데이터 전달하기 (Lifting State Up)

형제 컴포넌트가 데이터를 공유해야 하는 경우, 데이터를 부모 컴포넌트로 올리고 이를 다시 형제들에게 전달하는 방식이 일반적입니다.

코드 예제

function ParentComponent() {
  const [sharedData, setSharedData] = React.useState("");

  return (
    <div>
      <SiblingOne onUpdate={setSharedData} />
      <SiblingTwo data={sharedData} />
    </div>
  );
}

function SiblingOne({ onUpdate }) {
  const updateData = () => {
    onUpdate("Data from SiblingOne");
  };

  return <button onClick={updateData}>Update Data</button>;
}

function SiblingTwo({ data }) {
  return <p>Received: {data}</p>;
}

부모 컴포넌트가 상태를 관리하고, 형제 컴포넌트는 이 상태를 업데이트하거나 사용할 수 있습니다.

장점

  • 데이터 흐름이 명확하고 React의 철학에 부합합니다.

단점

  • 계층이 깊어질수록 상태 관리가 복잡해질 수 있습니다.

4. Context API 사용하기

Context API는 중첩된 컴포넌트 계층에서 데이터를 전달하기 위한 강력한 도구입니다. 이를 통해 props를 여러 단계에 걸쳐 전달하지 않고도 컴포넌트 트리 전체에서 데이터를 공유할 수 있습니다.

코드 예제

const DataContext = React.createContext();

function ParentComponent() {
  const data = "Shared data via Context";

  return (
    <DataContext.Provider value={data}>
      <ChildComponent />
    </DataContext.Provider>
  );
}

function ChildComponent() {
  const data = React.useContext(DataContext);
  return <p>{data}</p>;
}

DataContext.Provider는 데이터를 공급하고, 자식 컴포넌트는 useContext 훅을 사용해 데이터를 소비합니다.

장점

  • Prop Drilling 문제를 해결합니다.
  • 전역 상태 관리가 간단합니다.

단점

  • 상태 관리가 복잡해질 경우 Redux 같은 외부 상태 관리 도구가 필요할 수 있습니다.

5. 외부 상태 관리 도구 활용하기 (Redux, Zustand 등)

더 큰 규모의 애플리케이션에서는 전역 상태 관리 도구(예: Redux, Zustand, MobX)를 사용하는 것이 효율적일 수 있습니다. 이러한 도구는 애플리케이션의 상태를 중앙에서 관리하고, 컴포넌트 간 데이터를 더 쉽게 공유할 수 있게 합니다.

코드 예제 (Redux)

// actions.js
export const setData = (data) => ({ type: "SET_DATA", payload: data });

// reducer.js
const initialState = { data: "" };

function dataReducer(state = initialState, action) {
  switch (action.type) {
    case "SET_DATA":
      return { ...state, data: action.payload };
    default:
      return state;
  }
}

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

const store = createStore(dataReducer);

// App.js
import { Provider, useDispatch, useSelector } from "react-redux";
import { setData } from "./actions";

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

  return (
    <div>
      <button onClick={() => dispatch(setData("New Data"))}>Set Data</button>
      <ChildComponent />
    </div>
  );
}

function ChildComponent() {
  const data = useSelector((state) => state.data);
  return <p>{data}</p>;
}

function App() {
  return (
    <Provider store={store}>
      <ParentComponent />
    </Provider>
  );
}

이 예제는 Redux를 사용해 전역 상태를 관리하고, 데이터를 부모와 자식 컴포넌트 간에 공유합니다.

장점

  • 복잡한 상태를 효율적으로 관리할 수 있습니다.

단점

  • 설정이 복잡할 수 있습니다.

결론

React에서 컴포넌트 간 데이터를 전달하는 방법은 애플리케이션의 크기와 복잡도에 따라 달라질 수 있습니다. 소규모 애플리케이션에서는 Props와 Callback Props가 충분하지만, 더 큰 애플리케이션에서는 Context API나 Redux와 같은 외부 상태 관리 도구가 필요할 수 있습니다. 상황에 맞는 적절한 방법을 선택해 효율적으로 데이터를 관리해 보세요!

반응형