-
Props 요리조리 구워삶기 - Context API & Props DrillingREACT 2025. 12. 10. 15:13

오늘수업도 중요한 내용들을 배웠지만 나의 뇌용량은 터져나갔다
덕분에 아주 기초적인 props 개념도 혼란이 오기 시작,,,,,,,,,,ㅎ
그래도 흔들리지말고 하나부터 차근차근 개념을 쌓아나가보자 한다
기본적으로 Props는 객체이다.
Props로 부모에서 자식에게 정보를 전달 할수 있다는건 알고있다.
항상 {props.키값} 이런식으로 속성에 접근하는데 props 자체가 객체라는걸 눈치채지 못하고있었다.
(여기서 알아차렸어야하는데 바보같은 나는 한참멀었다ㅠ)
// props가 객체였던 몰랐던 나는 그걸 고대로 렌더링하려고 했다. function Child(props) { return <div>나는 {props}의 아들입니다!</div>; // 이렇게 쓰면 당연히 아무것도 안나옴 } // props를 확인해보고 싶은거라면 객체확인하듯이 속성키를 적던지 function Child(props) { return <div>나는 {props.motherName}의 아들입니다!</div>; } //아님 아래처럼 문자열로 변환해서 보던지, function Child(props) { return <div>props 객체: {JSON.stringify(props)}</div>; } // 콘솔에 찍어보는 방법도 있다 function Child(props) { console.log(props); return <div>나는 {props.motherName}의 아들입니다!</div>; }Props Drilling
저번수업에도 가볍게 프롭스 드릴링에 대해 설명을 들었는데 오늘 완죠니 딥하게 개념을 익혔다.
Props를 여러 자식들을 거쳐 (자식,손자,증손자,....) 전달해야하는 상황을 말한다
function App() { const user = "철수"; return <A user={user} />; } function A({ user }) { return <B user={user} />; // A는 user를 사용하지 않지만 전달만 함 } function B({ user }) { return <C user={user} />; // B도 user를 사용하지 않지만 전달만 함 } function C({ user }) { return <div>{user}님 환영합니다!</div>; // 여기서만 실제로 사용 }이럴때 A,B 컴포넌트들은 데이터가 필요없는데도 전달만 해야하는것이 굉장히 비효율적이게 되는 문제가 생긴다.
Context API로 해결가능.
이 방법은 props를 일일히 전달하지않고 필요한 컴포넌트가 직접 데이터를 가져올수 있게 할수있다.
쓰는방법은 아래와 같다.
1. context 생성
// UserContext.jsx import { createContext } from 'react'; export const UserContext = createContext(); // 🌟 context 객체를 생성하고 변수에 넣음2. Provider로 데이터 제공
// App.jsx import { UserContext } from './UserContext'; function App() { const user = "철수"; return ( <UserContext value={user}> // 🌟 객체안에 들어가있는 Provider속성을 쓰기위해 컴포넌트처럼 작성함 <A /> </UserContext> ); } function A() { return <B />; // props 전달 없음! } function B() { return <C />; // props 전달 없음! }react 18버전 까지는 Provider에 .provider를 붙였어야 햇는데 19버전부터 떼고 써도 작동되도록 패치되었다고 한다
ex) 18ver: <UserContext.Provider> </UserContext.Provider>
3. useContext로 데이터값 가져오기
// C.jsx import { useContext } from 'react'; import { UserContext } from './UserContext'; function C() { const user = useContext(UserContext); // 🌟데이터값 가져오기 return <div>{user}님 환영합니다!</div>; }useContext가 반복된다면? Custom Hook을 쓰자
import { useContext } from 'react'; //쓸때마다 매번 import을 불러와야한다 import { ThemeContext } from './ThemeContext'; function MyComponent() { const theme = useContext(ThemeContext); return <div>{theme}</div>; }이 예제는 context을 사용하기 위해 useContext를 반복적으로 import 시켜야한다
// useThemeContext.jsx import { useContext } from 'react'; import { ThemeContext } from './ThemeContext'; export function useThemeContext() { // useContext 전용 커스텀훅 하나 만들어주고 const theme = useContext(ThemeContext); //여기서 useContext 해주면됨 if (!theme) { throw new Error('useThemeContext는 ThemeProvider 안에서만 사용 가능!'); } return theme; } // MyComponent.jsx import { useThemeContext } from './useThemeContext'; // 그럼 import문도 하나 줄고 function MyComponent() { const theme = useThemeContext(); // useContext대신 커스텀훅만 불러주면 되니 간결함 return <div>{theme}</div>; }이때 theme 전용 훅을 커스텀해서 따로 생성해주면 useContext을 반복시킬일이 없다.
커스텀훅은 예제를 보면알겠지만 앞에 use를 붙이면 끝이다. 매우쉬움
그래서 커스텀훅을 재사용하면
- 코드가 간결해지고
- context 이름이 바뀌어도 한곳만 수정하면 되고
- 에러처리 로직도 추가를 할수있다는 장점이 있다
Context API를 남발하면 안 되는 이유
그렇다고 context가 다 좋은것은 아니다 당연히 단점도 있음
const UserContext = createContext(); function App() { const [user, setUser] = useState("철수"); const [age, setAge] = useState(25); return ( <UserContext value={{ user, age, setUser, setAge }}> <Profile /> <Settings /> </UserContext> ); } function Profile() { const { user } = useContext(UserContext); return <div>{user}</div>; } function Settings() { const { age, setAge } = useContext(UserContext); return <button onClick={() => setAge(age + 1)}>나이 증가</button>; }이 예제에선 Provider에서 age만 변경되어도 user만 쓰는 Profile 컴포넌트까지 리렌더링된다는 문제가 있다.
그러니까 단점1. context값이 바뀌면 그걸 쓰고있는 모든컴포넌트가 리렌더링이 된다는것이다.
단점2. props로 쓸땐 데이터흐름을 명확하게 볼수있는 반면 context는 파악이 어렵다는 점도 있다.
function Button() { const theme = useContext(ThemeContext); return <button style={{ color: theme.color }}>클릭</button>; //항상 ThemeContext가 있어야만 동작 }단점3. context를 쓰는 컴포넌트들은 재사용하기가 어려울수도 있다.
그럼 context을 사용하면 안되는경우는 뭐가 있을까
- 자주 변경되는 데이터 (검색어, 폼 입력 등)
- 2-3단계만 props로 전달하면 되는 경우
- 컴포넌트 재사용이 중요한 경우
여기서 만약 context조차도 복잡하게 느껴진다면
Zustand 같은 라이브러리도 고려해볼수있다
// Zustand 사용 예시 import { create } from 'zustand'; const useCountStore = create((set) => ({ count: 0, increase: () => set((state) => ({ count: state.count + 1 })), })); function Counter() { const count = useCountStore((state) => state.count); const increase = useCountStore((state) => state.increase); return <button onClick={increase}>{count}</button>; }주스탠드 장점은 Provider 없이 바로 쓸수있고 간결한 문법과 성능최적화가 자동으로 된다는것!
실제로 프로젝트에서 많이 쓰고 있는 라이브러리인데 사실 나는 이번에 처음봄,,
나중에 수업에서 한번 더 다루는거같던데 이런게 있다는 정도로만 디깅해보았다.
참고자료
https://nami-socket.tistory.com/61
Context API로 Props Drilling 올바르게 해결하기
작년에 React deep dive 스터디를 했었다. 당시 context API를 Props drilling을 해결하기 위한 의존성 주입 도구로 활용할 수 있다는 걸 배웠다. 하지만 실무에서 props drilling이 깊어질수록 복잡해졌고 무작
nami-socket.tistory.com
https://patterns-dev-kr.github.io/design-patterns/provider-pattern/
Provider 패턴
📜 원문: patterns.dev - provider pattern 앱 내의 여러 컴포넌트들이 데이터를 사용 할 수 있게 해야 하는 상황이 있다. props 를 통해서 데이터를 전달하는 방식이 있지만 앱 내의 모든 컴포넌트들이 데
patterns-dev-kr.github.io
https://yooneeee.tistory.com/49
[React] Props란, Props Children
🛫 Props란? - 프로퍼티, props(properties의 줄임말) - 부모 컴포넌트에서 자식 컴포넌트에게 물려준 데이터, 즉 컴포넌트간의 정보 교류 방식 - props는 반드시 위에서 아래(부모에서 자식)방향으로만
yooneeee.tistory.com
https://hyunki99.tistory.com/111
[React] Zustand란? 사용하는 이유! (상태 관리 라이브러리, 사용 방법 예시)
Zustand는 독일어로 '상태'라는 뜻으로 React 생태계에서 사용하는 상태 관리 라이브러리입니다. 현재 Redux가 압도적으로 많이 사용되고 있지만, 문법이 더러운 편이라 학습에 시간이 필요합니다. Po
hyunki99.tistory.com
'REACT' 카테고리의 다른 글
Virtual DOM부터 Memoization까지 (0) 2025.12.29 시작한건 끝내야하는 useEffect, 그리고 return (0) 2025.12.11 useState, 제대로 알고 쓰시나요? (0) 2025.12.09 굳이 createPortal로 모달을 만드는 이유는? (0) 2025.12.08 useReducer로 상태관리 연습해보기 (0) 2025.12.02