오늘도 코딩하나

[React] Crypto Tracker #2 - Props 없이 상태 관리하기 (Nested Router & Recoil) 본문

React/노마드코더

[React] Crypto Tracker #2 - Props 없이 상태 관리하기 (Nested Router & Recoil)

오늘도 코딩하나 2025. 2. 20. 18:22
강의 내용: 강의 링크
#5.11 ~ #6.4

 

1️⃣ nested router props 처리

  • react-router-dom v5에서는 prop를 직접 전달할 수 있지만,
  • react-router-dom v6에서는 prop를 직접 전달할 수 없으므로,
  • Outlet을 사용해 자식 컴포넌트가 부모의 데이터를 공유할 수 있도록 한다.

    ( 이유에 대한 자세한 설명은 nested Routes 설명 참고 👉 설명보러가기 )

// Coin.tsx
<Outlet context={{ coinId: coinId }} />
// Chart.tsx
interface IOutletProps {
  coinId: string;
}

function Chart() {
  const { coinId } = useOutletContext<IOutletProps>();
}

 

  📌 Outlet에서 context를 설정하면 자식 컴포넌트에서 useOutletContext()로 접근 가능함


 

2️⃣ state-management : Recoil

 

  state-management : 컴포넌트 간에 state를 효율적으로 공유하고 관리하는 방법

 

  ❓ state-management를 사용하는 이유 

     👉 비효율적인 상태 전달을 해결하기 위해!

// App.tsx
<ThemeProvider theme={isDark ? darkTheme : lightTheme}>
  <ReactQueryDevtools initialIsOpen={true} />
</ThemeProvider>
// Chart.tsx
function Chart({ isDark }: ChartProps) {
  return (
    <ApexChart
      options={{
        theme: { mode: isDark ? "dark" : "light" },
      }}
    />
  )
}

 

   ApexChart의 theme를 darkMode / lightMode에 따라 설정해주고 싶다고 하자

  일반적인 방법으로 props를 이용해 부모 → 자식으로 데이터를 전달해서 설정할 거다

App → Router   Coin Chart
  • App에서 만든 theme을 Chart에서 사용하려면 중간 컴포넌트를 불필요하게 거쳐야 한다.
    ( ∵ 중간 단계의 컴포넌트는 props만 전달하는 역할을 하게 되기 때문에)

  📌 이를 해결하기 위해 상태를 전역적으로 관리할 수 있는 State Management Library 필요하다!


  ➰ global state (전역 변수) 
        :
컴포넌트가 어디에 있든지, 누가 접근하고자 하는지에 상관없이 value에 접근해야할 때 사용한다

            (대표적인 예 : isLoggedIn)

 

  ➰ Recoil : ReactJS에서 사용할 수 있는 state management library
                    : 해당 value가 필요한 component만 그 value를 가진다. (중간다리 ❌)

// atoms.ts
import { atom } from "recoil";

export const isDarkAtom = atom({
  key: "isDark",
  default: true,
});
  • 어떤 component에서 어떤 value에 접근하려면, 먼저 필요한 value에 대한 atom을 형성한다.
  • atom은 key(고유구분키), default(기본값) 2개의  argument를 가진다.
// Chart.tsx
const isDark = useRecoilValue(isDarkAtom);

<ApexChart
  options={{
    theme: { mode: isDark ? "dark" : "light" },
  }}
/>
  • 해당 value가 필요하다면 component가 직접 atom에 연결한다.
    👉 useRecoilValue

  ✳ theme을 control할 수 있는 버튼을 만들어보자!

// Coins.tsx
const setDarkAtom = useSetRecoilState(isDarkAtom);
const toggleDarkAtom = () => setDarkAtom((prev) => !prev);

<button onClick={toggleDarkAtom}>Toggle Mode</button>
  • atom에서 value를 가져왔고, 버튼을 누를때만 setValue를 하고싶은 경우,
    👉 useSetRecoilState
    (쉽게 생각하면 setState와 같은 기능이다.)

  📌 오직 value가 필요한 component만 그 value를 가진다.

  📌 atom의 value를 감지하기 위해서는 useRecoilValue라는 Hook을 사용한다.

  📌 setValue를 하기 위해서는 useSetRecoilState라는 Hook을 사용한다.


3️⃣ Helmet
  * 상태 관리와 무관한 내용이지만, 강의 내용 중에 포함되어 있어 함께 정리합니다.

// App.tsx
<HelmetProvider>
  <Router />
</HelmetProvider>
// Coins.tsx
<Helmet>
  <title>코인</title>
</Helmet>

 

  📌 Helmet = head로 가는 direct link
        컴포넌트 기반으로 동작해서, 무엇을 render하던 <head>의 내용을 자동으로 변경함.