[React] Hooks

๋˜๋ ยท2023๋…„ 9์›” 4์ผ
0

React

๋ชฉ๋ก ๋ณด๊ธฐ
9/17
post-thumbnail

๐Ÿ”— ์ด๋ฏธ์ง€ : React hooks best practices in 2021

React๋ฅผ ์‚ฌ์šฉํ•˜๋‹ค ๋ณด๋ฉด ํ›…! ์ด๋ผ๋Š” ๊ฒƒ์„ ์ž์ฃผ ์ ‘ํ•˜๊ฒŒ ๋œ๋‹ค.

๐ŸŽฃ Hook ์ด ๋ญ”๋ฐ?

๋ฆฌ์•กํŠธ v16.8์— ์ƒˆ๋กœ ๋„์ž…๋œ ๊ธฐ๋Šฅ์œผ๋กœ ๊ธฐ์กด์˜ ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ์—์„œ ํ•  ์ˆ˜ ์—†์—ˆ๋˜ ๋‹ค์–‘ํ•œ ์ž‘์—…์„ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด ์ค€๋‹ค.
๐Ÿ“– React๋ฅผ ๋‹ค๋ฃจ๋Š” ๊ธฐ์ˆ  ์ฑ… ๋‚ด์šฉ

๋ฌธ์žฅ๋งŒ ๋ด์„œ๋Š” ๋„์ €ํžˆ ํ›…์— ๋Œ€ํ•ด ๊ฐ์ด ์•ˆ์˜ค๋Š”๋ฐ, ์‚ฌ์‹ค ๋ฆฌ์•กํŠธ๋ฅผ ๋ง‰ ์ฒ˜์Œ ๋ฐฐ์šฐ๋ฉด์„œ ๊ฐ’์„ ๋งŒ์ง€๋Š” ์ž‘์—…์„ ํ–ˆ๋Š”๋ฐ ๊ทธ๋•Œ ์ด๋ฏธ ํ›…์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์—ˆ๋‹ค๋Š” ์‚ฌ์‹ค...!

์•„๋ž˜์—์„œ๋„ ๋‹ค๋ฃจ๊ฒ ์ง€๋งŒ ๋ฐ”๋กœ useState๋ผ๋Š” ํ›…์ด๋‹ค.

์šฐ์„  ํ›…์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์ƒ๋‹จ์— ์‚ฌ์šฉํ•  ํ›…์„ importํ•ด์•ผํ•œ๋‹ค.
์˜ˆ๋ฅผ ๋“ค์–ด useState๋ผ๋Š” ํ›…์„ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ๋‹ค! ๊ทธ๋Ÿฌ๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ์ž‘์„ฑํ•ด ์ฃผ๋ฉด ๋œ๋‹ค.

import { useState } from 'react';

์ด๋Ÿฐ์‹์œผ๋กœ ์šฐ์„  ์‚ฌ์šฉํ•  ํ›…์„ import ํ›„ ์ž์œ ๋กญ๊ฒŒ ์‚ฌ์šฉํ•˜๋ฉด ๋!
์ด๋ฒˆ ๊ธ€์—์„œ๋Š” ๊ฐ ํ›…์ด ๋ฌด์—‡์ธ์ง€ ์–ด๋–ค ๋•Œ์— ์‚ฌ์šฉ๋˜๋Š”์ง€ ์ •๋ฆฌํ•ด ๋ณด์•˜๋‹ค.

๐ŸŽฃ useState

import { useState } from 'react';

const Counter = () => {
  const [value, setValue] = useState(0);
  
  return (
    <div>
    	<p>ํ˜„์žฌ ์นด์šดํ„ฐ ๊ฐ’์€ <b>{value}</b> ์ž…๋‹ˆ๋‹ค.</p>
    	<button onClick={()=> setValue(value + 1)}> +1 ํ•˜๊ธฐ</button>
    	<button onClick={()=> setValue(value - 1)}> -1 ํ•˜๊ธฐ</button>
    </div>
  )
}

๊ฐ„๋‹จํ•œ ์นด์šดํ„ฐ๋ฅผ useState ํ›…์„ ์‚ฌ์šฉํ•ด์„œ ๋งŒ๋“  ์ฝ”๋“œ๋‹ค.

const [value, setValue] = useState(0);

value๋Š” ์ƒํƒœ ๊ฐ’์ด๊ณ  setValue๋Š” ์ƒํƒœ๋ฅผ ์„ค์ •ํ•œ๋‹ค.
useState์˜ ()์•ˆ์—๋Š” ์ดˆ๊ธฐ๊ฐ’์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ, ๋ณดํ†ต ๋ฌธ์ž์ด๋ฉด ('')์œผ๋กœ ํ‘œํ˜„ํ•˜๊ณ  ์ˆซ์ž๋ฉด (0)์„ ์ดˆ๊ธฐ๊ฐ’์œผ๋กœ ์…‹ํŒ… ํ•ด ๋‘”๋‹ค.

์ด ํ•จ์ˆ˜์— ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ๋„ฃ์–ด ํ˜ธ์ถœํ•˜๋ฉด ์ „๋‹ฌ๋ฐ›์€ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๊ฐ’์ด ๋ฐ”๋€Œ๊ณ  ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ฆฌ๋ Œ๋”๋ง ๋œ๋‹ค.


๐ŸŽฃ useEffect

useState๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ฐ’์ด ๋ฐ”๋€” ๋•Œ๋งˆ๋‹ค ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ฆฌ๋ Œ๋”๋ง์ด ๋œ๋‹ค.

ํ•˜์ง€๋งŒ ๋งŒ์•ฝ ๋ถˆํ•„์š”ํ•œ ๋ฆฌ๋ Œ๋”๋ง์„ ๋ฐฉ์ง€ํ•œ๋‹ค๋ฉด ์กฐ๊ธˆ์€ ์„ฑ๋Šฅ์„ ํ–ฅ์ƒ ์‹œํ‚ฌ ์ˆ˜ ์žˆ์ง€ ์•Š์„๊นŒ?
๊ทธ๋ž˜์„œ ๋ฐ”๋กœ useEffect ๋ผ๋Š” ํ›…์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ถˆํ•„์š”ํ•œ ๋ฆฌ๋ Œ๋”๋ง์„ ์กฐ๊ธˆ์€ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ๋‹ค!

import { useState, useEffect } from "react";
import ReactDOM from "react-dom/client";

function Timer() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    setTimeout(() => {
      setCount((count) => count + 1);
    }, 1000);
  });

  return <h1>I've rendered {count} times!</h1>;
}

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Timer />);

์šฐ์„  ์œ„์™€ ๊ฐ™์€ ํƒ€์ด๋จธ๊ฐ€ ์žˆ๋‹ค๊ณ  ํ•˜์ž.
์‹คํ–‰์„ ์‹œ์ผœ๋ณด๋ฉด 1์ดˆ๋งˆ๋‹ค count๊ฐ€ 1์”ฉ ์ฆ๊ฐ€ํ•˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

์ฆ‰, ๊ณ„์† ๋ฆฌ๋ Œ๋”๋ง์„ ํ•˜๋ฉด์„œ count๋ฅผ ์ฆ๊ฐ€ ์‹œํ‚ค๊ณ  ์žˆ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

๊ทธ๋ ‡๋‹ค๋ฉด ์ตœ์ดˆ ๋ Œ๋”๋งํ• ๋•Œ๋งŒ ์‹คํ–‰๋˜๊ณ  ์—…๋ฐ์ดํŠธ๋  ๋•Œ๋Š” ์‹คํ–‰์‹œํ‚ค์ง€ ์•Š์œผ๋ ค๋ฉด?
์ด๋Ÿด๋•Œ ๋ฐ”๋กœ useEffect์˜ 2๋ฒˆ์งธ ํŒŒ๋ผ๋ฏธํ„ฐ์— ๋นˆ ๋ฐฐ์—ด([])์„ ์ถ”๊ฐ€ํ•ด ์ฃผ๋ฉด ๋œ๋‹ค.

import { useState, useEffect } from "react";
import ReactDOM from "react-dom/client";

function Timer() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    setTimeout(() => {
      setCount((count) => count + 1);
    }, 1000);
  }, []); // <- useEffect์˜ 2๋ฒˆ์งธ ํŒŒ๋ผ๋ฏธํ„ฐ์— ๋นˆ ๋ฐฐ์—ด ์ถ”๊ฐ€!

  return <h1>I've rendered {count} times!</h1>;
}

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Timer />);

์œ„์™€ ๊ฐ™์ด ์ถ”๊ฐ€๋ฅผ ํ•˜๊ณ  ๋‚˜๋ฉด ํƒ€์ด๋จธ๋Š” ์ตœ์ดˆ ๋ Œ๋”๋ง ์‹œ ์‹คํ–‰๋งŒ ํ•˜๊ณ  ์ฆ๊ฐ€ํ•˜์ง€ ์•Š๋Š”๋‹ค.
์ฆ‰ ๋งˆ์šดํŠธ๋  ๋•Œ๋งŒ ์‹คํ–‰๋œ๋‹ค.

์—‡ ๊ทธ๋Ÿฌ๋ฉด ํŠน์ • ๊ฐ’์ด ์—…๋ฐ์ดํŠธ๋  ๋•Œ๋งŒ ์‹คํ–‰์‹œํ‚ค๊ณ  ์‹ถ์„ ๋• ์–ด๋–ป๊ฒŒ ํ• ๊นŒ?
๋ฐ”๋กœ ๋นˆ ๋ฐฐ์—ด์— ๊ทธ ํŠน์ • ๊ฐ’์„ ๋„ฃ์–ด์ฃผ๋ฉด ๋œ๋‹ค!

import { useState, useEffect } from "react";
import ReactDOM from "react-dom/client";

function Counter() {
  const [count, setCount] = useState(0);
  const [calculation, setCalculation] = useState(0);

  useEffect(() => {
    setCalculation(() => count * 2);
  }, [count]); // <- count๊ฐ’์ด ๋ณ€๊ฒฝ๋˜๋ฉด ์—…๋ฐ์ดํŠธ๊ฐ€ ๋œ๋‹ค!

  return (
    <>
      <p>Count: {count}</p>
      <button onClick={() => setCount((c) => c + 1)}>+</button>
      <p>Calculation: {calculation}</p>
    </>
  );
}

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Counter />);

์ด๋ ‡๊ฒŒ ์›ํ•˜๋Š” ๊ฐ’์„ ์—…๋ฐ์ดํŠธ๋  ๋•Œ ์‹คํ–‰์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค.


๐ŸŽฃ useReducer

useReducer๋Š” useState์™€ ๊ต‰์žฅํžˆ ์œ ์‚ฌํ•œ ํ›…์ด๋‹ค.
์‚ฌ์‹ค ๋ฆฌ๋“€์„œ๋Š” ๋ฆฌ๋•์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด์„œ ๋ฐฐ์šฐ๊ฒŒ ๋œ ํ›…์ด์˜€๋Š”๋ฐ ๊ฐ„๋‹จํžˆ ์ •๋ฆฌ๋ฅผ ํ•˜๊ณ  ๋„˜์–ด๊ฐ€ ๋ณด๊ฒ ๋‹ค.

import { useReducer } from 'react';

function reducer (state, action) {
	switch (action.type) {
      case 'INCREMENT' :
        return { value : state.value + 1};
      case 'DECREMENT' :
        return { value : state.value - 1};
      default :
        return state;
    }
}

const Counter = () => {
	const [state, dispatch] = useReducer(reducer, {value : 0})
}

return (
	<div>
  		<p>ํ˜„์žฌ ์นด์šดํ„ฐ ๊ฐ’์€ <b>{state.value}</b> ์ž…๋‹ˆ๋‹ค.</p>
  		<button onClick={()=> dispatch({type: 'INCREMENT'})}> +1 ์ฆ๊ฐ€</button>
		<button onClick={()=> dispatch({type: 'DECREMENT'})}> -1 ๊ฐ์†Œ</button>
  	</div>
)

๋ฆฌ๋“€์„œ์˜ ์ฒซ๋ฒˆ์งธ ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” ๋ฆฌ๋“€์„œ ํ•จ์ˆ˜๋ฅผ, ๋‘๋ฒˆ์งธ ํŒŒ๋ผ๋ฏธํ„ฐ์—๋Š” ๊ธฐ์ดˆ๊ฐ’์„ ๋„ฃ์–ด์ค€๋‹ค.

dispatch()๋Š” ๋ฆฌ๋“€์„œ์˜ ํƒ€์ž…์— ๋”ฐ๋ฅธ return๋˜๋Š” ๋ถ€๋ถ„์„ ์‹คํ–‰์‹œํ‚จ๋‹ค.
๋ฆฌ๋“€์„œ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด dispatch๋Š” ํ•„์ˆ˜๋กœ ๋”ฐ๋ผ๋‹ค๋‹ˆ๋Š” ๋‹จ์ง ์นœ๊ตฌ ๊ฐ™์€ ์กด์žฌ!


๐ŸŽฃ useMemo

useMomo๋Š” ์ข€ ๋…ํŠนํ•œ ํ›…์ด๋‹ค. ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ ๋‚ด๋ถ€์—์„œ ๋ฐœ์ƒํ•˜๋Š” ์—ฐ์‚ฐ์„ ์ตœ์ ํ™”ํ•˜๋Š” ์šฉ๋„๋กœ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

const memoizedValue = useMemo(() => {
  // ์—ฌ๊ธฐ์— ๊ณ„์‚ฐ ๋น„์šฉ์ด ๋†’์€ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.
  // ๊ทธ ๊ฒฐ๊ณผ๋ฅผ memoizedValue์— ์ €์žฅํ•˜๊ณ  ์žฌ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
  return someComputedValue;
}, [dependency1, dependency2]);

useMemo์˜ ์ฒซ๋ฒˆ์งธ ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ํ•จ์ˆ˜๋ฅผ ๋ฐ›๊ณ  ์ด ํ•จ์ˆ˜ ์•ˆ์—์„œ ๊ณ„์‚ฐ ๋น„์šฉ์ด ๋†’์€ ์ž‘์—…์„ ์ˆ˜ํ–‰ ํ›„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
๋‘๋ฒˆ์งธ ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ์˜์กด์„ฑ ๋ฐฐ์—ด์ธ๋ฐ ์ด ๋ฐฐ์—ด์— ํฌํ•จ๋œ ๊ฐ’์„ ๋ณ€ํ™”ํ•  ๋•Œ๋งŒ useMomo ๋‚ด๋ถ€์˜ ํ•จ์ˆ˜๊ฐ€ ๋‹ค์‹œ ์‹คํ–‰๋œ๋‹ค. ๋งŒ์•ฝ ๋ณ€ํ™”๊ฐ€ ์—†๋‹ค๋ฉด ์ด์ „์— ๊ณ„์‚ฐํ•œ ๊ฒฐ๊ณผ๋ฅผ ์žฌ์‚ฌ์šฉํ•œ๋‹ค.

์‚ฌ์‹ค useMemo์˜ ์‚ฌ์šฉ์ฒ˜๊ฐ€ ์–ด๋”œ๊นŒ ๊ถ๊ธˆํ–ˆ๋Š”๋ฐ ๋งˆ์นจ GPT๊ฐ€ ์ข‹์€ ์˜ˆ์‹œ๋ฅผ ๋“ค์–ด ์ฃผ์—ˆ๋‹ค.

๐Ÿค– : useMemo๋Š” React์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๋„๊ตฌ ์ค‘ ํ•˜๋‚˜๋กœ, ์ฃผ๋กœ ๊ณ„์‚ฐ์ด ๋ณต์žกํ•˜๊ฑฐ๋‚˜ ์‹œ๊ฐ„์ด ์˜ค๋ž˜ ๊ฑธ๋ฆฌ๋Š” ์ž‘์—…์˜ ๊ฒฐ๊ณผ๋ฅผ ์ €์žฅํ•˜๊ณ  ํ•„์š”ํ•  ๋•Œ ์žฌ์‚ฌ์šฉํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์„ฑ๋Šฅ์„ ํ–ฅ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ฐ„๋‹จํ•œ ์˜ˆ๋ฅผ ๋“ค์–ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ๊ฐ€์ƒ์˜ ์‡ผํ•‘ ์›น์‚ฌ์ดํŠธ๋ฅผ ๋งŒ๋“ ๋‹ค๊ณ  ์ƒ์ƒํ•ด๋ด…์‹œ๋‹ค. ์‚ฌ์šฉ์ž๊ฐ€ ์ƒํ’ˆ ๋ชฉ๋ก์„ ์—ด ๋•Œ๋งˆ๋‹ค ๋ชจ๋“  ์ƒํ’ˆ์˜ ๊ฐ€๊ฒฉ์„ ๋‹ค์‹œ ๊ณ„์‚ฐํ•œ๋‹ค๋ฉด ๋งค๋ฒˆ ์‹œ๊ฐ„์ด ์˜ค๋ž˜ ๊ฑธ๋ฆด ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๋Ÿฐ ์ƒํ™ฉ์—์„œ useMemo๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ฒ˜์Œ ํ•œ ๋ฒˆ ๊ฐ€๊ฒฉ์„ ๊ณ„์‚ฐํ•œ ๋‹ค์Œ, ๊ทธ ๊ฐ’์„ ์ €์žฅํ•˜๊ณ , ์‚ฌ์šฉ์ž๊ฐ€ ๋ชฉ๋ก์„ ๋‹ค์‹œ ์—ด ๋•Œ๋งˆ๋‹ค ๊ณ„์‚ฐ์„ ๋‹ค์‹œ ํ•˜์ง€ ์•Š๊ณ  ์ €์žฅ๋œ ๊ฐ’์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ฐ„๋‹จํžˆ ๋งํ•ด, useMemo๋Š” ๋น„์‹ผ ๊ณ„์‚ฐ์„ ์ €๋ ดํ•˜๊ฒŒ ๋งŒ๋“ค์–ด์ฃผ๋Š” ๋„๊ตฌ์ž…๋‹ˆ๋‹ค. ๊ณ„์‚ฐ ๊ฒฐ๊ณผ๋ฅผ ๊ธฐ์–ตํ•˜๊ณ , ํ•„์š”ํ•  ๋•Œ ๋น ๋ฅด๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ค๋‹ˆ๋‹ค.


๐ŸŽฃ useCallback

useCallback์€ useMemo์™€ ๋น„์Šทํ•œ๋ฐ, ๋ Œ๋”๋ง ์„ฑ๋Šฅ์„ ์ตœ์ ํ™”ํ•ด์•ผ ํ•˜๋Š” ์ƒํ™ฉ์—์„œ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.
์ด ์นœ๊ตฌ๋„ useMemo์ฒ˜๋Ÿผ ์ฒซ๋ฒˆ์งธ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ํ•จ์ˆ˜๋ฅผ ์ „๋‹ฌํ•˜๊ณ , ๋‘๋ฒˆ์งธ ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ์˜์กด์„ฑ ๋ฐฐ์—ด์ด๋‹ค.

function ParentComponent() {
  const handleClick = useCallback(() => {
    console.log('Button clicked');
  }, []); // ์˜์กด์„ฑ ๋ฐฐ์—ด์ด ๋น„์–ด์žˆ์œผ๋ฏ€๋กœ ํ•ญ์ƒ ๊ฐ™์€ ํ•จ์ˆ˜๋ฅผ ์žฌ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

  return <ChildComponent onClick={handleClick} />;
}

function ChildComponent({ onClick }) {
  return <button onClick={onClick}>Click me</button>;
}

useCallback์„ ์‚ฌ์šฉํ•œ ์˜ˆ์‹œ์ธ๋ฐ, handleClick ํ•จ์ˆ˜๊ฐ€ ParentComponent๊ฐ€ ๋ Œ๋”๋ง๋  ๋•Œ๋งˆ๋‹ค ์ƒˆ๋กœ ์ƒ์„ฑ๋˜์ง€ ์•Š๊ณ  ํ•œ ๋ฒˆ ์ƒ์„ฑ๋œ ํ•จ์ˆ˜๋ฅผ ๊ณ„์† ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋„์™€์ค€๋‹ค. ์ด๋ ‡๊ฒŒ ์„ฑ๋Šฅ ๊ฐœ์„ ํ•˜๋Š”๋ฐ ๋„์›€์ด ๋œ๋‹ค๋Š” ๊ฒƒ!


๐ŸŽฃ useRef

useRef๋Š” ์•„์ง์€ ํฌ์ปค์Šค๋ฅผ ์ž๋™์œผ๋กœ ๊ฐ€๊ฒŒ ํ•˜๋Š” ์ƒํ™ฉ์—์„œ๋ฐ–์— ์‚ฌ์šฉ์„ ์•ˆํ–ˆ๋‹ค.
๋‹ค๋ฅธ ์˜ˆ์ œ๋„ ๋Œ€๋ถ€๋ถ„์ด ์˜คํ†  ํฌ์ปค์Šค๋ฅผ ์‚ฌ์šฉํ• ๋•Œ ์‚ฌ์šฉํ•ด์„œ ๐Ÿ˜… ์ด ๋ถ€๋ถ„์€ ์ข€ ๋” ๋ฆฌ์•กํŠธ๋ฅผ ๋‹ค๋ค„๋ณด๋ฉด์„œ ํ™•์žฅ ์‹œ์ผœ ๋‚˜๊ฐ€์•ผ ๊ฒ ๋‹ค.

import { useRef } from "react";
import ReactDOM from "react-dom/client";

function App() {
  const inputElement = useRef();

  const focusInput = () => {
    inputElement.current.focus();
  };

  return (
    <>
      <input type="text" ref={inputElement} />
      <button onClick={focusInput}>Focus Input</button>
    </>
  );
}

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);

์œ„์™€ ๊ฐ™์ด ์˜คํ†  ํฌ์ปค์Šค๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ input์— ref๋ฅผ ๋‘๊ณ  useRef๋ฅผ ์‚ฌ์šฉํ•˜๊ฒ ๋‹ค๊ณ  ์ง€์ •ํ•œ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ์ด๋ฒคํŠธ๋ฅผ ์ด์šฉํ•ด์„œ current.focus();๋กœ ์ง€์ •ํ•˜๋ฉด ์ž๋™์œผ๋กœ ํฌ์ปค์Šค๊ฐ€ ๋‚ด๊ฐ€ ์ง€์ •ํ–ˆ๋˜ input์œผ๋กœ ์ด๋™ํ•˜๊ฒŒ ๋œ๋‹ค.
์—ฌ๊ธฐ์„œ ํฌ์ธํŠธ๋Š” current.focus() ํ•ด์•ผ ๋œ๋‹ค๋Š” ๊ฒƒ! current๊ฐ€ ๊ผญ๊ผญ ํ•„์š”ํ•˜๋‹ค.

๐Ÿ“– ์ฝ”๋“œ ์ถœ์ฒ˜: w3scools.com , ๋ฆฌ์•กํŠธ๋ฅผ ๋‹ค๋ฃจ๋Š” ๊ธฐ์ˆ 

profile
โœจ ๐‘ฌ๐’—๐’†๐’“๐’š๐’•๐’‰๐’Š๐’๐’ˆ ๐’„๐’๐’Ž๐’†๐’” ๐’•๐’ ๐’‰๐’Š๐’Ž ๐’˜๐’‰๐’ ๐’‰๐’–๐’”๐’•๐’๐’†๐’” ๐’˜๐’‰๐’Š๐’๐’† ๐’‰๐’† ๐’˜๐’‚๐’Š๐’•๐’”. โœจ

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