Skip to content

Latest commit

Β 

History

History
210 lines (178 loc) Β· 5.85 KB

Managing React Application State Management - Talk by Kent C. Dodds.md

File metadata and controls

210 lines (178 loc) Β· 5.85 KB

두 가지 μƒνƒœ

  1. μ„œλ²„ μΊμ‹œ
  • μ„œλ²„μ— μ €μž₯λ˜μ–΄ μžˆλŠ” 정보이며, 이λ₯Ό λΉ λ₯΄κ²Œ μ‚¬μš©μžμ—κ²Œ 보여주기 μœ„ν•΄μ„œ ν΄λΌμ΄μ–ΈνŠΈ μ‚¬μ΄λ“œμ— μƒνƒœλ‘œμ„œ μΊμ‹±ν•΄λ†“λŠ”λ‹€.
  • 맀번 λ°±μ—”λ“œλ‘œ μš”μ²­μ„ λ³΄λ‚΄λŠ” λŒ€μ‹ , λ°±μ—”λ“œμ™€ ν”„λ‘ νŠΈμ—”λ“œ 사이에 μΊμ‹œλΌλŠ” λ ˆμ΄μ–΄λ₯Ό λ‘μ–΄μ„œ μ„±λŠ₯상 문제λ₯Ό ν•΄κ²°ν•˜λŠ” 것.
  1. UI μƒνƒœ
  • ν”„λ‘ νŠΈμ—”λ“œμ—λ§Œ μ €μž₯λ˜μ–΄μžˆλŠ” μƒνƒœ.
  • νŽ˜μ΄μ§€ μƒˆλ‘œκ³ μΉ¨μ‹œ λͺ¨λ‘ μ‚¬λΌμ§€λŠ” μƒνƒœ.

이 두가지 μƒνƒœλŠ” λ‹€λ₯΄κ²Œ μ²˜λ¦¬λ˜μ–΄μ•Ό ν•œλ‹€. μ„œλ²„ μΊμ‹œλŠ” λ¦¬μ•‘νŠΈ 쿼리, 리코일 같은 μƒνƒœκ΄€λ¦¬ λΌμ΄λΈŒλŸ¬λ¦¬μ—μ„œ ν•Έλ“€λ§ν•˜κ³ , λ¦¬μ•‘νŠΈμ—μ„œλŠ” UI μƒνƒœλ§Œ 닀루도둝 ν•˜μž.

UI μƒνƒœ

  • λͺ¨λ“ κ±Έ μ „μ—­μœΌλ‘œ λ‘”λ‹€λ©΄ κ²°κ΅­ App (μ΅œμƒμœ„μ»΄ν¬λ„ŒνŠΈ)μ—μ„œ κ΄€λ¦¬ν•˜λŠ”κ²Œ κΈ°ν•˜κΈ‰μˆ˜μ μœΌλ‘œ 늘 수 밖에 μ—†λ‹€. (Prop Drilling)
  • 그러면 μ–΄λ–»κ²Œ ν•΄κ²°ν•΄μ•Όν• κΉŒ?

ν•©μ„± μ΄μš©ν•˜κΈ°

function App() {
  const [someState, setSomeState] = React.useState("some state");
  return (
    <>
      <Header
        logo={<Logo someState={someState} />}
        settings={<Settings onStateChange={setSomeState} />}
      />
      <LeftNav>
        <SomeLink someState={someState} />
        <SomeOtherLink someState={someState} />
        <Etc someState={someState} />
      </LeftNav>
      {/* ... */}
    </>
  );
}

λ§Œμ•½β€¦ν•©μ„±μ΄ μΆ©λΆ„ν•˜μ§€ μ•Šλ‹€λ©΄ Context λ₯Ό μ‚¬μš©ν•˜μ„Έμš©

ν•©μ„± κ΄€λ ¨ μ˜μƒ YouTube

Context api κ΄€λ ¨ κΈ€ How to use React Context effectively

Context

const CountContext = React.createContext()

function Counter() {
  const {count, increment} = React.useContext(CountContext)
  return <button onClick={onIncrementClick}>{count}</button>
}

function CountDisplay() {
  const {count} = React.useContext(CountContext)
  return <div>The current counter count is {count}</div>
}

function App() {
  const [count, setCount] = React.useState(0)
  const increment = () => setCount(c => c + 1)
  return (
    <CountContext.Provider value={{count, increment}}>
      <div>
        <CountDisplay />
        <Counter />
      </div>
    </CountContext.Provider>
  )

Colocate States

  • κΈ€λ‘œλ²Œμ— λͺ¨λ“  μƒνƒœλ₯Ό λ†“λŠ”λ‹€λ©΄β€¦
function App() {
  return (
    <UserProvider username={username}>
      <NotificationsProvider>
        <ThemeProvider>
          <AuthenticationProvider>
            <Router>
              <HomeScreen path="/" />
              <AboutScreen path="/about" />
              <UserScreen path="/:userId" />
              <UserSettingsScreen path="/settings" />
              <NotificationsScreen path="/notifications" />
            </Router>
          </AuthenticationProvider>
        </ThemeProvider>
      </NotificationsProvider>
    </UserProvider>
  );
}
  • μœ„μ™€ 같은 μ»΄ν¬λ„ŒνŠΈ ꡬ쑰라면 μ•„λž˜μ™€ 같은 파일 ꡬ쑰λ₯Ό κ°–κ²Œλœλ‹€.
my-cool-app
└── src
    β”œβ”€β”€ index.js
    β”œβ”€β”€ providers
    β”‚Β Β  β”œβ”€β”€ auth.js
    β”‚Β Β  β”œβ”€β”€ notifications.js
    β”‚Β Β  β”œβ”€β”€ theme.js
    β”‚Β Β  β”œβ”€β”€ user.js
    β”‚Β Β  └── ...etc
    β”œβ”€β”€ screens
    β”‚Β Β  β”œβ”€β”€ about.js
    β”‚Β Β  β”œβ”€β”€ home.js
    β”‚Β Β  β”œβ”€β”€ notifications
    β”‚Β Β  β”‚Β Β  β”œβ”€β”€ index.js
    β”‚Β Β  β”‚Β Β  β”œβ”€β”€ list.js
    β”‚Β Β  β”‚Β Β  β”œβ”€β”€ tab.js
    β”‚Β Β  β”‚Β Β  └── type-list.js
    β”‚Β Β  β”œβ”€β”€ settings.js
    β”‚Β Β  └── user
    β”‚Β Β      β”œβ”€β”€ activity.js
    β”‚Β Β      β”œβ”€β”€ index.js
    β”‚Β Β      β”œβ”€β”€ info.js
    β”‚Β Β      └── nav.js
    └── utils
        └── ...etc
  • 문제점 : Notification Provider λŠ” notification μ»΄ν¬λ„ŒνŠΈμ—μ„œλ§Œ μ“°λŠ”λ° ν•΄λ‹Ή λ‘œμ§μ„ μˆ˜μ •ν•˜κΈ° μœ„ν•΄μ„œλŠ” 각 폴더λ₯Ό 널뛰기 해야함…

  • 문제점 2: μžλ°”μŠ€ν¬λ¦½νŠΈ νŒŒμΌμ„ λ‘œλ“œ ν•  λ•Œ.. μ‚¬μš©μžμ—κ²Œ Notification μ»΄ν¬λ„ŒνŠΈκ°€ 보이기 μ „μ΄λ‚˜ Setting μ»΄ν¬λ„ŒνŠΈκ°€ 보이기도 전에 provider κ΄€λ ¨ μ½”λ“œκ°€ λ‘œλ“œλ˜λ©΄μ„œ λΆˆν•„μš”ν•œ λ‘œλ”©μ΄ 생겨버린닀. -> μ½”λ“œ μŠ€ν”Œλ¦ΏνŒ… λΆˆκ°€λŠ₯

κ·Έλž˜μ„œ μ•„λž˜μ™€ 같이 colocate ν•˜μž!

function App() {
  return (
    <ThemeProvider>
      <AuthenticationProvider>
        <Router>
          <HomeScreen path="/" />
          <AboutScreen path="/about" />
          <UserScreen path="/:userId" />
          <UserSettingsScreen path="/settings" />
          <NotificationsScreen path="/notifications" />
        </Router>
      </AuthenticationProvider>
    </ThemeProvider>
  );
}

function NotificationsScreen() {
  return (
    <NotificationsProvider>
      <NotificationsTab />
      <NotificationsTypeList />
      <NotificationsList />
    </NotificationsProvider>
  );
}

function UserScreen({ username }) {
  return (
    <UserProvider username={username}>
      <UserInfo />
      <UserNav />
      <UserActivity />
    </UserProvider>
  );
}
my-cooler-app
└── src
    β”œβ”€β”€ index.js
    β”œβ”€β”€ providers
    β”‚Β Β  β”œβ”€β”€ auth.js
    β”‚Β Β  β”œβ”€β”€ theme.js
    β”‚Β Β  └── ...etc
    β”œβ”€β”€ screens
    β”‚Β Β  β”œβ”€β”€ about.js
    β”‚Β Β  β”œβ”€β”€ home.js
    β”‚Β Β  β”œβ”€β”€ notifications
    β”‚Β Β  β”‚Β Β  β”œβ”€β”€ index.js
    β”‚Β Β  β”‚Β Β  β”œβ”€β”€ list.js
    β”‚Β Β  β”‚Β Β  β”œβ”€β”€ provider.js
    β”‚Β Β  β”‚Β Β  β”œβ”€β”€ tab.js
    β”‚Β Β  β”‚Β Β  └── type-list.js
    β”‚Β Β  β”œβ”€β”€ settings.js
    β”‚Β Β  └── user
    β”‚Β Β      β”œβ”€β”€ activity.js
    β”‚Β Β      β”œβ”€β”€ index.js
    β”‚Β Β      β”œβ”€β”€ info.js
    β”‚Β Β      β”œβ”€β”€ nav.js
    β”‚Β Β      └── provider.js
    └── utils
        └── ...etc