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개의 λŒ“κΈ€