avatar
Published on

React Hooks Api (1)

Author
  • avatar
    Name
    yceffort

Hooks API

Hook์€ react 16.8์—์„œ ์ถ”๊ฐ€๋œ ๊ฐœ๋…์œผ๋กœ, Hook์„ ์‹œ์šฉํ•˜๋ฉด class๋ฅผ ๊ฐ–์„ฑํ•˜์ง€ ์•Š์•„๋„ state๊ด€๋ฆฌ์™€ ๊ฐ™์€ react์˜ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

๊ธฐ๋ณธ Hook

useState

const [state, setState] = useState(initialState)
setState(newState)

์ƒํƒœ ์œ ์ง€๊ฐ’, ๊ทธ๋ฆฌ๊ณ  ๊ทธ ๊ฐ’์„ ์ˆ˜์ •ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค. ์ด์ „์˜ state๊ฐ’์„ ๋ฐ›์•„๋‹ค๊ฐ€ ์ˆ˜์ •ํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

function Counter({initialCount}) {
  const [count, setCount] = useState(initialCount)
  return (
    <>
      Count: {count}
      <button onClick={() => setCount(initialCount)}>Reset</button>
      <button onClick={() => setCount((prevCount) => prevCount + 1)}>+</button>
      <button onClick={() => setCount((prevCount) => prevCount - 1)}>-</button>
    </>
  )
}

๋™์ผํ•œ ๊ฐ’์œผ๋กœ ๊ฐฑ์‹ ํ•˜๋Š” ๊ฒฝ์šฐ(Object.is) ๊ฐ’์ด ์—…๋ฐ์ดํŠธ ํ•˜์ง€ ์•Š๊ณ  ์ฒ˜๋ฆฌ๋ฅผ ์ข…๋ฃŒํ•œ๋‹ค.

useEffect

useEffect(didUpdate)

ํ™”๋ฉด์— ๋ Œ๋”๋ง์ด ์™„๋ฃŒ๋œ ์ดํ›„์— ์ˆ˜ํ–‰ํ•œ๋‹ค. ๋˜ํ•œ, ์ปดํฌ๋„ŒํŠธ๊ฐ€ ํ™”๋ฉด์—์„œ ์ œ๊ฑฐ ๋  ๋•Œ ์ •๋ฆฌ ํ•ด์•ผํ•  ๋ฆฌ์†Œ์Šค๋„ ์„ ์–ธํ•  ์ˆ˜ ์žˆ๋‹ค.

useEffect(() => {
  const subscription = props.source.subscribe()
  return () => {
    subscription.unsubscribe()
  }
})

unsubscribe๋Š” ์ด์ œ ui์—์„œ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ œ๊ฑฐํ•˜๊ธฐ ์ง์ „์— ์ˆ˜ํ–‰ํ•œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋งŒ์•ฝ, ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์—ฌ๋Ÿฌ๋ฒˆ ๋ Œ๋”๋ง ๋œ๋‹ค๋ฉด ๋‹ค์Œ effect๊ฐ€ ์ˆ˜ํ–‰๋˜๊ธฐ ์ „์— ์ด์ „ effect๊ฐ€ ์ •๋ฆฌ๋œ๋‹ค.

๋งŒ์•ฝ ์กฐ๊ฑด๋ถ€๋กœ ์‹คํ–‰ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์•„๋ž˜์™€ ๊ฐ™์€ ๋ฐฉ๋ฒ•์„ ํ™œ์šฉํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

useEffect(() => {
  const subscription = props.source.subscribe()
  return () => {
    subscription.unsubscribe()
  }
}, [props.source])

๊ทธ๋Ÿผ ์ด์ œ props.source๊ฐ’์ด ๋ณ€๊ฒฝ ๋ ๋•Œ ๋งŒ useEffect๊ฐ€ ๋ฐœ์ƒํ•˜๊ฒŒ ๋œ๋‹ค.

useContext

Context

context๋ฅผ ์ด์šฉํ•˜๋ฉด, ๋งค๋ฒˆ ์ผ์ผ์ด props๋ฅผ ๋„˜๊ฒจ์ฃผ์ง€ ์•Š์•„๋„, ์ปดํฌ๋„ŒํŠธ ํŠธ๋ฆฌ์ „์ฒด์— ๋ฐ์ดํ„ฐ๋ฅผ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ๋‹ค. ์ฆ‰, context๋Š” react ์ปดํฌ๋„ŒํŠธ ํŠธ๋ฆฌ์•ˆ์—์„œ ์ „์—ญ์ ์œผ๋กœ ๋Œ€์ดํ„ฐ๋ฅผ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ณ ์•ˆ๋œ ๋ฐฉ๋ฒ•์ด๋‹ค.

<Page user={user} avatarSize={avatarSize} />
  <PageLayout user={user} avatarSize={avatarSize} />
    <NavigationBar user={user} avatarSize={avatarSize} />
      <Link href={user.permalink}>
        <Avatar user={user} size={avatarSize} />
      </Link>
    </NavigatorBar>
  </PageLayout>
</Page>

์‹ค์ œ๋กœ user์™€ avatarSize๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ณณ์€ Link์ปดํฌ๋„ŒํŠธ ์ธ๋ฐ, page ์˜จ๊ฐ– ์ปดํฌ๋„ŒํŠธ๋ฅผ ๊ฑฐ์น˜๋ฉด์„œ ๊ฐ’์„ ๋‚ด๋ ค์ฃผ๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. ์ด๊ฒŒ ๋” ์‹ฌํ•ด์ง€๋Š” ๊ฒฝ์šฐ, ๊ฐ™์€ ๋ฐ์ดํ„ฐ๋ฅผ ํŠธ๋ฆฌ์•ˆ์˜ ์—ฌ๋Ÿฌ ๋ ˆ๋ฒจ์˜ ์ปดํฌ๋„ŒํŠธ์—๊ฒŒ ์ฃผ์–ด์•ผ ํ•  ๋•Œ๋„ ์žˆ๋‹ค. ์ด๋ ‡๊ฒŒ ๋ฐ์ดํ„ฐ๊ฐ€ ๋ณ€ํ•  ๋•Œ ๋งˆ๋‹ค ๋ชจ๋“  ํ•˜์œ„ ์ปดํฌ๋„ŒํŠธ์—๊ฒŒ ํ•ด๋‹น ๊ฐ’์„ ์•Œ๋ ค์ฃผ๋Š” ๊ฒƒ์ด context์ด๋‹ค.

const MyContext = React.createContext(defaultValue)

Context๊ฐ์ฒด๋ฅผ ๋งŒ๋“ ๋‹ค. Context ๊ฐ์ฒด๋ฅผ ๊ตฌ๋…ํ•˜๊ณ , ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ Œ๋”๋ง ํ•  ๋•Œ ํŠธ๋ฆฌ ์ƒ์œ„์—์„œ ๊ฐ€์žฅ ๊ฐ€๊นŒ์ด ์ง์ด ๋งž๋Š” Provider๋กœ ๋ถ€ํ„ฐ ํ˜„์žฌ ๊ฐ’์„ ์ฝ๋Š”๋‹ค. ์—ฌ๊ธฐ์„œ ์„ ์–ธ๋œ defaultValue๋Š” ํŠธ๋ฆฌ์•ˆ์—์„œ ์ ์ ˆํ•œ Provider๋ฅผ ์ฐพ์ง€ ๋ชปํ–ˆ์„ ๋•Œ์—๋งŒ ์“ฐ๋Š” ๊ฐ’์ด๋‹ค.

<MyContext.provider value="{someValue}">
  <SomeComponent />
</MyContext.provider>

Provider๋Š” context๋ฅผ ๊ตฌ๋…ํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ๋“ค์—๊ฒŒ context์˜ ๋ณ€ํ™”๋ฅผ ์•Œ๋ฆฌ๋Š” ์—ญํ• ์„ ํ•œ๋‹ค. Provider๋Š” value์— ์žˆ๋Š” prop์„ ๋ฐ›์•„์„œ ์ด ๊ฐ’์„ ํ•˜์œ„ ์ปดํฌ๋„ŒํŠธ์— ์ „๋‹ฌํ•œ๋‹ค.

<MyContext.Consumer>
  {value => /* context ๊ฐ’์„ ์ด์šฉํ•œ ๋ Œ๋”๋ง */}
</MyContext.Consumer>

context ๋ณ€ํ™”๋ฅผ ๊ตฌ๋…ํ•˜๋Š” React Component๋‹ค. ๋ฐ˜๋“œ์‹œ Context.Consumer์˜ ์ž์‹์€ ํ•จ์ˆ˜์—ฌ์•ผ๋งŒ ํ•œ๋‹ค. ์ด ํ•จ์ˆ˜๋Š” context์˜ ํ˜„์žฌ ๊ฐ’์„ ๋ฐ›๊ณ , React ๋…ธ๋“œ๋ฅผ ๋ฐ˜ํ™˜ํ•ด์•ผ ํ•œ๋‹ค.

const value = useContext(MyContext)

๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด, context๊ฐ์ฒด๋ฅผ ๋ฐ›์•„์„œ, ํ˜„์žฌ context์˜ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.