React Hook ๋ฝ€๊ฐœ๊ธฐ with TS ๐Ÿ‘Š

Paul Kangยท2021๋…„ 10์›” 2์ผ
0

๋ฆฌ์•กํŠธ Hook ์•Œ์•„๋ณด์ž (TS ver.) โœ

1. useState

๊ธฐ๋ณธ ๊ผด

import React, { useState } from "react"

// array destructuring
const [user, setUser] = useState(null);

์ธ์ž๋กœ ๋ฐ›์€ ๊ฐ’์ด ์ƒํƒœ์˜ ์ดˆ๊ธฐ๊ฐ’์ž…๋‹ˆ๋‹ค. user ๋ผ๋Š” ๋ณ€์ˆ˜์— ์ดˆ๊ธฐ๊ฐ’ null์„ ์ €์žฅํ•˜๊ณ  setUser ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด user ๋ณ€์ˆ˜์— ๋‹ด๊ธด ์ƒํƒœ๊ฐ’์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์—ฌ๊ธฐ์„œ ์ž ๊น, ๋ฆฌ์•กํŠธ์˜ ํŠน์„ฑ์„ ์•Œ๊ณ  ๋„˜์–ด๊ฐ‘์‹œ๋‹ค.

๋ฆฌ์•กํŠธ์˜ ํŠน์ง• ์ค‘ ํ•˜๋‚˜, ์ƒํƒœ๊ฐ’์ด ๋ณ€๊ฒฝ๋˜๋ฉด Virtual DOM์ด ํ•ด๋‹น ์ƒํƒœ๊ฐ’์ด ์‚ฌ์šฉ๋œ ๋ถ€๋ถ„๋งŒ ๋‹ค์‹œ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค.
๊ทธ๋Ÿฌ๋‚˜ setUser ์™€ ๊ฐ™์€ ์ƒํƒœ๊ฐ’ ๋ณ€๊ฒฝ ํ•จ์ˆ˜๊ฐ€ ์•„๋‹Œ ์‚ฌ์šฉ์ž๊ฐ€ ์ž„์˜๋กœ ์ƒํƒœ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜๋ฉด ๋ฆฌ์•กํŠธ๋Š” ๋ณ€๊ฒฝ์‚ฌํ•ญ์„ ์ธ์‹ํ•˜์ง€ ๋ชปํ•˜๊ณ  ๋ฆฌ๋ Œ๋”๋ง์„ ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ƒํƒœ๊ฐ’์„ ๋ณ€๊ฒฝํ•  ๋•Œ ๋ฐ˜๋“œ์‹œ ์ƒํƒœ๊ฐ’ ๋ณ€๊ฒฝ ํ•จ์ˆ˜(setUser)๋ฅผ ์‚ฌ์šฉํ•ฉ์‹œ๋‹ค.

์˜ˆ์‹œ (TS ver.)

import { useState } from 'react';

type AuthUser = {
  name: string
  email: string
}

export const User = () => {

  const [user, setUser] = useState<AuthUser>({} as AuthUser); // 1๏ธโƒฃ
  
  return (
    <div>
      <div>User name is {user.name}</div>
      <div>User email is {user.email}</div>
    </div>
  )
}

1๋ฒˆ ๋ถ€๋ถ„์„ ์ œ์™ธํ•˜๋ฉด JS ํ™˜๊ฒฝ์—์„œ์˜ useState ์“ฐ๋Š” ๋ฐฉ๋ฒ•๊ณผ ๋™์ผํ•ฉ๋‹ˆ๋‹ค.
1๋ฒˆ ๋ผ์ธ์—์„œ <> ์•ˆ์— AuthUser๋ผ๋Š” Type์„ ํŠน์ •ํ•ด์ค€ ๊ฒƒ์ด๊ณ  ์ธ์ž๊ฐ’์€ ์ดˆ๊ธฐ ์ƒํƒœ๊ฐ’์ธ๋ฐ {} as AuthUser ์—์„œ as AuthUser ๋Š” Type Assertion ์ด๋ผ๋Š” ๊ฐœ๋…์ž…๋‹ˆ๋‹ค. ์ฆ‰, ์ดˆ๊ธฐ๊ฐ’์€ ๋นˆ ๊ฐ์ฒด์ด์ง€๋งŒ ์ด ๋นˆ ๊ฐ์ฒด์˜ ํƒ€์ž…์€ AuthUser ๋ผ๋Š” ๊ฒƒ์„ ๊ฐœ๋ฐœ์ž๊ฐ€ ์ง€์ •ํ•ด์ค€ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

Type Assertion ์€ ๊ฐœ๋ฐœ์ž๊ฐ€ ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ ์ปดํŒŒ์ผ๋Ÿฌ๋ณด๋‹ค ์ด ์ƒํƒœ(state)์— ๋Œ€ํ•ด์„  ๋” ์ž˜ ์•Œ๊ณ  ์žˆ๋‹ค, ์ด ์ƒํƒœ์˜ ํƒ€์ž…์€ ์–ด๋–ค ํŠน์ •ํ•œ ํƒ€์ž…๋งŒ ์˜ฌ ์ˆ˜ ์žˆ๋‹ค ๊ฐ™์€ ์ด๋Ÿฐ ์ƒํ™ฉ์—์„œ๋งŒ ์‚ฌ์šฉํ•˜๋„๋ก ํ•ฉ์‹œ๋‹ค.

์œ„ ์˜ˆ์‹œ ์ฝ”๋“œ์˜ ์ƒํ™ฉ์€ user๊ฐ’์ด ํ•ญ์ƒ ์กด์žฌํ•˜๋Š” ์ƒํ™ฉ(ํ˜น์€ user๊ฐ’์ด null์ด ๋  ์ˆ˜ ์—†๋Š” ์ƒํ™ฉ) ์—์„œ ๊ฐ€๋Šฅํ•œ ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค.

2. useEffect

  • useEffect๋Š” ๋ชจ๋“  ์‚ฌ์ด๋“œ ์ดํŽ™ํŠธ๋ฅผ ๋‹ด๋‹นํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ๋“ค๋ฉด, ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜, data fetch๋ฅผ ํ•˜๊ฑฐ๋‚˜...
  • componentDidUpdate, componentDidMount, componentWillUnmount
    ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ฒ˜์Œ ๋งˆ์šดํŠธ ๋  ๋•Œ / ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์—…๋ฐ์ดํŠธ ๋  ๋•Œ / ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์–ธ๋งˆ์šดํŠธ ๋  ๋•Œ ์ผ์–ด๋‚˜๋Š” ๋™์ž‘์„ ๋‹ด๋‹นํ•ฉ๋‹ˆ๋‹ค.

๊ธฐ๋ณธ ๊ผด

const [name, setName] = useState('Paul');
useEffect(() => {
  document.title = `Hello ${name}'s world!`;
}, [name])

์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋งˆ์šดํŠธ ๋˜์—ˆ์„ ๋•Œ ๋ธŒ๋ผ์šฐ์ € title์„ "Hello Paul's world!"๋กœ ๋ฐ”๊ฟ”์ค๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  name ์ƒํƒœ๊ฐ’์ด ๋ณ€๊ฒฝ๋˜์–ด ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์—…๋ฐ์ดํŠธ ๋˜์—ˆ์„ ๋•Œ๋„ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค.

clean up function๋„ ์•Œ๊ณ  ๋„˜์–ด๊ฐ‘์‹œ๋‹ค.
import React, {useEffect} from 'react'

  useEffect(
    (effect function)
    return {
      (cleanup function)
    }
  }, [dependencies]);

์ดํŽ™ํŠธ ํ•จ์ˆ˜ ํ˜ธ์ถœ ์‹œ์ ์€ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ฒ˜์Œ ๋งˆ์šดํŠธ๋  ๋•Œ, ์˜์กด๊ฐ’์œผ๋กœ ์ฃผ์–ด์ง„ ๊ฐ’์ด ๋ณ€๊ฒฝ๋  ๋•Œ๋ผ๊ณ  ๋ง์”€๋“œ๋ ธ์Šต๋‹ˆ๋‹ค.

๊ทธ๋ ‡๋‹ค๋ฉด ํด๋ฆฐ์—… ํ•จ์ˆ˜๋Š”?
์ดํŽ™ํŠธํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋˜๊ธฐ ์ „, ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์–ธ๋งˆ์šดํŠธ(unmount)๋  ๋•Œ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค.
์ด์ „ ์ดํŽ™ํŠธ๋กœ ์ธํ•œ ๊ฒฐ๊ณผ๋ฅผ ์ •๋ฆฌํ•ด์ฃผ๋Š” ์—ญํ• ์ž…๋‹ˆ๋‹ค. ๋ง๊ทธ๋Œ€๋กœ cleanup!

๊ทธ๋ฆฌ๊ณ  ์˜์กด๊ฐ’์ด ๋น„์–ด์žˆ๋‹ค๋ฉด ์ตœ์ดˆ ๋งˆ์šดํŠธํ•  ๋•Œ๋งŒ ์ดํŽ™ํŠธํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. ๋˜ ์˜์กด๊ฐ’์ด ์•„์˜ˆ ์กด์žฌํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ Œ๋”๋ง๋  ๋•Œ๋งˆ๋‹ค ์ดํŽ™ํŠธ๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. (์กฐ์‹ฌํ•ด์•ผ๊ฒ ์ฃ ?)

import { useState, useEffect } from "react";

const Test = () => {
  const [windowScrollY, setWindowScrollY] = useState<number>(window.scrollY);
  const handleScroll = () => {
    setWindowScrollY(window.scrollY);
  };
  useEffect(() => {
    window.addEventListener("scroll", handleScroll);
    console.log("effect");
    return () => {
      window.removeEventListener("resize", handleScroll);
      console.log("clean up");
    };
  }, [windowScrollY]);
  return <div style={{ height: '500vh' }}>{windowScrollY}</div>;
}

export default Test;

  • ์Šคํฌ๋กค์„ ๋‚ด๋ฆด๋•Œ๋งˆ๋‹ค cleanupํ•จ์ˆ˜๊ฐ€ ๋จผ์ € ํ˜ธ์ถœ๋˜๊ณ  ์ •๋ฆฌ๋ฅผ ํ•˜๊ณ  ๋‚˜์„œ effectํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
profile
๋ญ๋“  ๊ธฐ๋กํ•˜๋ฉด ์ž์‚ฐ!

0๊ฐœ์˜ ๋Œ“๊ธ€

๊ด€๋ จ ์ฑ„์šฉ ์ •๋ณด

Powered by GraphCDN, the GraphQL CDN