Design-loving front-end engineer
Ryong
Design-loving front-end engineer
์ „์ฒด ๋ฐฉ๋ฌธ์ž
์˜ค๋Š˜
์–ด์ œ
    • Framework
    • React
      • Concept
      • Library
      • Hook
      • Component
      • Test
    • NodeJS
    • Android
      • Concept
      • Code
      • Sunflower
      • Etc
    • Flutter
      • Concept
      • Package
    • Web
    • Web
    • CSS
    • Language
    • JavaScript
    • TypeScript
    • Kotlin
    • Dart
    • Algorithm
    • Data Structure
    • Programmers
    • Management
    • Git
    • Editor
    • VSCode
    • Knowledge
    • Voice
Design-loving front-end engineer

Ryong

[ React ]  Hook
React/Concept

[ React ] Hook

2022. 5. 28. 19:41

๐Ÿ”ด  useState

 
const [ state, setState ] = useState(0);  // ๋ณ€์ˆ˜ ์„ ์–ธ

// setState ํ•จ์ˆ˜์˜ ์ฒซ ๋ฒˆ์งธ argument๋Š” ํ˜„์žฌ state ๊ฐ’์ด๋‹ค.
setState((current) => current + 1);  // ๊ฐ’ ๋ณ€๊ฒฝ(๋น„๋™๊ธฐ) + ๋ Œ๋”๋ง
state = state + 1;                   // ๊ฐ’ ๋ณ€๊ฒฝ(๋น„๋™๊ธฐ)
 
// ๐Ÿ” state ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜๋Š” ๋ฐฉ๋ฒ•
const [fruit, setFruit] = useState({ color: "red", name: "apple" });

// 1๏ธโƒฃ ์ƒˆ๋กœ์šด ๊ฐ์ฒด ๋งŒ๋“ค๊ธฐ
setFruit({ color: "red", name: "strawberry" });
// 2๏ธโƒฃ prevState ๊ฐ’์„ ์ด์šฉํ•˜์—ฌ ์ด์ „ state๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ
setFruit(prev => ({ ...prev, name: "strawberry" }));

โšช  state์— ๋ฐฐ์—ด ๊ณ„์—ด์„ ์ง€์ •ํ•  ๋•Œ๋Š” setState์— ์ƒˆ๋กœ์šด ๋ฐฐ์—ด(spread, new Set)์„ ์ง€์ •ํ•ด์ค˜์•ผ ๋ Œ๋”๋ง์ด ์ผ์–ด๋‚œ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด state๊ฐ€ ๋ฐฐ์—ด์˜ ๊ฐ’์ด ์•„๋‹Œ ๋ฐฐ์—ด์˜ ์ฃผ์†Ÿ๊ฐ’์„ ๊ฐ€๋ฆฌํ‚ค๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ’์ด ๋ณ€ํ•˜์ง€ ์•Š์•˜๋‹ค๊ณ  ํŒ๋‹จํ•˜์—ฌ ๋ Œ๋”๋ง์ด ์ผ์–ด๋‚˜์ง€ ์•Š๋Š”๋‹ค.

 

๐ŸŸ   useEffect

โšช  ๋ Œ๋”๋ง ํ›„ ํŠน์ •ํ•œ ์‹œ๊ธฐ์—๋งŒ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๊ธฐ ์œ„ํ•œ Hook

  โšช  ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์‹œ์ž‘๋  ๋•Œ ์‹คํ–‰ํ•  ์ง€, ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋๋‚  ๋•Œ ์‹คํ–‰ํ•  ์ง€ ์•„๋‹ˆ๋ฉด ๋ฌด์–ธ๊ฐ€ ๋ณ€ํ•  ๋•Œ ์‹คํ–‰ํ•  ์ง€ ์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

 
import { useEffect } from "react";

useEffect(effect, [deps]);

โšช  effect

  โšช  ์ปดํฌ๋„ŒํŠธ ๋ Œ๋”๋ง ์ดํ›„ ์‹คํ–‰ํ•  ํ•จ์ˆ˜

  โšช  ๋ฆฌ์•กํŠธ๋Š” ์ด ํ•จ์ˆ˜๋ฅผ ๊ธฐ์–ตํ–ˆ๋‹ค๊ฐ€ DOM ์—…๋ฐ์ดํŠธ ์ดํ›„ ๋ถˆ๋Ÿฌ๋‚ธ๋‹ค.

โšช  deps

 
useEffect(() => {
    console.log("useEffect");
});

  โšช  deps ๋ฐฐ์—ด ์ธ์ž๊ฐ€ ์—†์„ ๊ฒฝ์šฐ, ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ Œ๋”๋ง ๋  ๋•Œ๋งˆ๋‹ค useEffect๊ฐ€ ์‹คํ–‰๋œ๋‹ค.

 
useEffect(() => {
    console.log("useEffect");
}, []);

  โšช  ๋นˆ ๋ฐฐ์—ด์„ ์ธ์ž๋กœ ๋„ฃ์„ ๊ฒฝ์šฐ, ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ฒ˜์Œ ์ƒ์„ฑ๋  ๋•Œ์—๋งŒ ์‹คํ–‰๋œ๋‹ค.

 
useEffect(() => {
    console.log("useEffect");
}, [count]);

  โšช  ํŠน์ • ๋ณ€์ˆ˜๋ฅผ ๋ฐฐ์—ด ์š”์†Œ๋กœ ๋„ฃ์„ ๊ฒฝ์šฐ, ์ดˆ๊ธฐ ๋ Œ๋”๋ง ์งํ›„์™€ ํ•ด๋‹น ๋ณ€์ˆ˜์˜ ๊ฐ’์ด ๋ณ€๊ฒฝ๋  ๋•Œ๋งŒ ์‹คํ–‰๋œ๋‹ค.

 
useEffect(() => {
    console.log("useEffect");
    return () => console.log("goodbye");
}, [count]);

  โšช  ํ•จ์ˆ˜๋ฅผ return ํ•  ๊ฒฝ์šฐ, ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์‚ฌ๋ผ์งˆ ๋•Œ(์–ธ๋งˆ์šดํŠธ ๋  ๋•Œ) return ๋˜๋Š” ํ•จ์ˆ˜๊ฐ€ ๋งˆ์ง€๋ง‰์œผ๋กœ ํ•œ ๋ฒˆ ์‹คํ–‰๋œ๋‹ค.

 

๐ŸŸก  useRef

๐Ÿ“Œ  useRef๋Š” ์ปดํฌ๋„ŒํŠธ์˜ DOM ๋…ธ๋“œ์— ์ง์ ‘ ์ ‘๊ทผํ•  ๋•Œ ์ฃผ๋กœ ์‚ฌ์šฉํ•œ๋‹ค.

โšช  useRef๋Š” current๋ผ๋Š” ๊ฐ’์„ ๋‹ด๊ณ  ์žˆ๋Š” ์ƒ์ž์ด๋ฉฐ, ๋ฐ˜ํ™˜๋œ ๊ฐ์ฒด๋Š” ์ปดํฌ๋„ŒํŠธ์˜ ์ „ ์ƒ์• ์ฃผ๊ธฐ๋ฅผ ํ†ตํ•ด ์œ ์ง€๋œ๋‹ค.

โšช  Reference๋Š” ๋…ธ๋“œ์— ๋Œ€ํ•œ ์ฃผ์†Œ ์ •๋ณด๋ฅผ ๋‹ด๊ณ  ์žˆ๋‹ค. ๋ฆฌ์•กํŠธ์—์„œ๋Š” current์— ์ด๋Ÿฌํ•œ ref ์ฃผ์†Œ๋ฅผ ๋‹ด๊ณ  ์žˆ๋‹ค.

โšช  ์˜ˆ๋ฅผ ๋“ค๋ฉด, <div ref={myRef} /> ์™€ ๊ฐ™์ด ์„ ์–ธํ•˜๋ฉด, myRef.current์— div์˜ DOM ๋…ธ๋“œ์— ๋Œ€ํ•œ ์ฃผ์†Œ๊ฐ’์„ ์ €์žฅํ•œ๋‹ค.

 
// input ๋…ธ๋“œ์— ์ ‘๊ทผํ•ด์„œ focus() ๋ถ€์—ฌ
const focusBtn = () => {
  const inputEl = useRef(null);
  const handleClick = () => {
    inputEl.current.focus();
  };
  return (
    <>
      <input ref={inputEl} type="text" />
      <button onClick={onClick}>Focus input</button>
    </>
  );
}
 
// ํ•ด๋‹น ๋…ธ๋“œ์—์„œ ํ„ฐ์น˜ ์‹œ ์ผ์–ด๋‚˜๋Š” ์ด๋ฒคํŠธ ๋ฒ„๋ธ”๋ง ์ค‘๋‹จํ•˜๊ธฐ
import { useEffect, useRef } from "react";

const Component = () => {
  const targetRef = useRef(null);
  useEffect(() => {
    const handleTouch = (event) => {
      console.log(event.target);
      event.stopPropagation();  // ์ด๋ฒคํŠธ ๋ฒ„๋ธ”๋ง ์ค‘๋‹จ
    }
    const element = targetRef.current;
    // ref์— ์ด๋ฒคํŠธ ๋ถ€์—ฌ
    element.addEventListener("touchstart", handleClick);
    element.addEventListener("touchend", handleClick);
    return () => {
      element.removeEventListener("touchstart", handleClick);
      element.removeEventListener("touchend", handleClick);
    }
  }, []);
  
  return (
    <div ref={targetRef}></div>
  );
}

 

๐Ÿ“Œ  useRef์˜ ๋˜ ๋‹ค๋ฅธ ํŠน์ง•์€ setter๊ฐ€ ์—†์–ด์„œ ๊ฐ’์ด ๋ณ€๊ฒฝ๋˜์–ด๋„ ๋ฆฌ๋ Œ๋”๋ง ํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

 

๐ŸŸข  useLayoutEffect

โšช  useLayoutEffect ํ˜ธ์ถœ ์ˆœ์„œ

  ๐Ÿ”‰  ๋ Œ๋”๋ง

  ๐Ÿ”‰  useLayoutEffect  ํ˜ธ์ถœ

  ๐Ÿ”‰  ๋ธŒ๋ผ์šฐ์ € ํ™”๋ฉด ๊ทธ๋ฆฌ๊ธฐ : ์ด ์‹œ์ ์— ์ปดํฌ๋„ŒํŠธ์— ํ•ด๋‹นํ•˜๋Š” ์—˜๋ฆฌ๋จผํŠธ๊ฐ€ ์‹ค์ œ๋กœ DOM์— ์ถ”๊ฐ€๋จ

  ๐Ÿ”‰  useEffect ํ˜ธ์ถœ

 
// ๐Ÿ” ์˜ˆ์‹œ : ์ฐฝ์˜ ํฌ๊ธฐ๊ฐ€ ๋ฐ”๋€ ๊ฒฝ์šฐ ์—˜๋ฆฌ๋จผํŠธ ๋„ˆ๋น„์™€ ๋†’์ด ๋ฐ›๊ธฐ
function useWindowSize {
    const [ width, setWidth ] = useState(0);
    const [ height, setHeight ] = useState(0);
    
    const resize = () => {
        setWidth(window.innerWidth);
        setHeight(window.innerHeight);
    };
    
    useLayoutEffect(() => {
        window.addEventListener("resize", resize);
        resize();
        return () => window.removeEventListener("resize", resize);
    }, []);
    
    return [width, height];
};

 

์ €์ž‘์žํ‘œ์‹œ

'React > Concept' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

[ React ] Props  (0) 2022.07.14
[ React ] ์›น ์†Œ์ผ“ ํ†ต์‹  + Web Audio API  (0) 2022.06.02
    'React/Concept' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€
    • [ React ] Props
    • [ React ] ์›น ์†Œ์ผ“ ํ†ต์‹  + Web Audio API
    Design-loving front-end engineer
    Design-loving front-end engineer
    ๋””์ž์ธ์— ๊ด€์‹ฌ์ด ๋งŽ์€ ๋ชจ๋ฐ”์ผ ์•ฑ ์—”์ง€๋‹ˆ์–ด Ryong์ž…๋‹ˆ๋‹ค.

    ํ‹ฐ์Šคํ† ๋ฆฌํˆด๋ฐ”