๐Ÿ“

13. Hook - useRef

ย 
useRef๋Š” ์ˆœ์ˆ˜ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
const refContainer = useRef(initialValue);
ย 
์ปดํฌ๋„ŒํŠธ์˜ โ€œํƒœ๊ทธ(tag)โ€์— ์ง์ ‘ ์ ‘๊ทผํ•˜๊ณ  ์‹ถ์„ ๋•Œ useRef๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ DOM element๋ฅผ ๊ฐ€์ง€๊ณ  ์˜ฌ ๋•Œ querySelector๋‚˜ getElementById๋ฅผ ์‚ฌ์šฉํ•˜์ง€๋งŒ React์—์„œ๋Š” useRef๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ ๋ Œ๋”๋ง๊ณผ ์ƒ๊ด€์—†์ด ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜๊ณ  ์‹ถ์„ ๋•Œ๋„ useRef๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
ย 
์ด๋•Œ useRef๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ useRef๊ฐ€ ์ ‘๊ทผํ•œ ํƒœ๊ทธ ์š”์†Œ์˜ ๊ฐ’์„ ๋ฐ”๊ฟ€ ๋•Œ๋Š” ๋ฆฌ๋ Œ๋”๋ง์„ ๋ฐœ์ƒ์‹œํ‚ค์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์„ ๊ธฐ์–ตํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค. ๋ฐ์ดํ„ฐ, state์™€ ์ƒ๊ด€์—†์ด(๋ฆฌ๋ Œ๋”๋ง ํ•˜์ง€ ์•Š๊ณ ) component์— DOM์„ ์ œ์–ดํ•˜๊ณ  ์‹ถ์„ ๋•Œ ref๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. Ref๋Š” ๋‚จ์šฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋จผ์ € ref๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ ๋„ ๋‹ค๋ฅธ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜์—ฌ์„œ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ๊ณ ๋ คํ•œ ํ›„ ์‚ฌ์šฉํ•˜์„ธ์š”
ย 
React์—์„œ๋„ return๋ฌธ์— ์žˆ๋Š” ์š”์†Œ๋“ค์—๊ฒŒ id๊ฐ’์„ ์ฃผ๊ณ  ์„ ํƒ์ž ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด๋„ ์ข‹์ง€๋งŒ(๊ธฐ์กด์— ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋ฐฉ์‹), React์— ๊ฐ€์žฅ ํฐ ์žฅ์ ์ธ ์žฌ์‚ฌ์šฉ์„ฑ์„ ์ƒ๊ฐํ•œ๋‹ค๋ฉด ์‚ฌ์šฉ์„ ๊ถŒ์žฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
์ปดํฌ๋„ŒํŠธ๋ฅผ ์žฌ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ ๋™์ผํ•œ id๊ฐ’์„ ๊ฐ€์ง„ ์š”์†Œ๊ฐ€ ์ƒ๊ธฐ๊ธฐ ๋•Œ๋ฌธ์ด์ฃ ! (์žฌ์‚ฌ์šฉ ์•ˆํ•œ๋‹ค ํ•˜๋”๋ผ๋„ ์ง์ ‘ id๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ์ค‘๋ณต์˜ ๊ฒฝ์šฐ๊ฐ€ ์ƒ๊ธธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.) ๊ทธ๋ž˜์„œ id๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋Œ€์‹  ref๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ref๋Š” ์ „์—ญ์œผ๋กœ ์ž‘๋™ํ•˜์ง€์•Š๊ณ  ์ปดํฌ๋„ŒํŠธ ๋‚ด๋ถ€์—์„œ๋งŒ ์ž‘๋™ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.(์žฌ์‚ฌ์šฉํ•  ๋•Œ ๊ฐ™์€ ์ปดํฌ๋„ŒํŠธ์ง€๋งŒ ๋‹ค๋ฅด๊ฒŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.) ๋งŒ์•ฝ id๋ฅผ ์‚ฌ์šฉํ•˜๊ณ ์ž ํ•œ๋‹ค๋ฉด ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“ค ๋•Œ๋งˆ๋‹ค id ๋’ท๋ถ€๋ถ„์— id name์„ ์ถ”๊ฐ€ํ•˜์—ฌ ์œ ๋‹ˆํฌํ•œ id๋กœ ๋งŒ๋“ค์–ด์ค˜์•ผ ํ•ฉ๋‹ˆ๋‹ค.
ย 

useRef ์‚ฌ์šฉํ•ด ๋ด…์‹œ๋‹ค!

ย 
  1. ์ด๋ฉ”์ผ input๊ณผ ๋น„๋ฐ€๋ฒˆํ˜ธ input์˜ ์ž…๋ ฅ์ด ์™„๋ฃŒ๋œ ํ›„ ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด span ๋ถ€๋ถ„์— ์ž…๋ ฅํ–ˆ๋˜ ์ด๋ฉ”์ผ๊ณผ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ๋ณด์—ฌ์ฃผ๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค.
ย 
button์—์„œ ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด inputCheck์—์„œ ๋น„๋ฐ€๋ฒˆํ˜ธ์™€ ์ด๋ฉ”์ผ์˜ ๊ฐ’์„ ๋ฐ›์•„์™€์„œ setEmailValue, setPwValue๋ฅผ ์‹คํ–‰ํ•ด์ค˜์„œ ์ƒํƒœ๊ฐ’์„ ๋ณ€๊ฒฝํ•ด์ฃผ๋ฉด ๋ฉ๋‹ˆ๋‹ค.
import React, { useState } from "react"; const App = () => { const [emailValue, setEmailValue] = useState(""); // email state ๊ฐ’ const [pwValue, setPwValue] = useState(""); // pw state ๊ฐ’ const inputCheck = (e) => { e.preventDefault(); }; return ( <form style={{ display: "flex", flexDirection: "column" }}> <label> ์ด๋ฉ”์ผ : <input type="email" /> </label> <label> ๋น„๋ฐ€๋ฒˆํ˜ธ : <input type="password" /> </label> <button type="submit" style={{ width: "100px" }} onClick={inputCheck}> ๋กœ๊ทธ์ธ </button> <span>์ž…๋ ฅํ•œ ์ด๋ฉ”์ผ : {emailValue}</span> <span>์ž…๋ ฅํ•œ ๋น„๋ฐ€๋ฒˆํ˜ธ : {pwValue}</span> </form> ); }; export default App;
src / App.js state ์ถ”๊ฐ€ํ•˜๊ธฐ
ย 
์ด๋•Œ input์˜ ๊ฐ’์„ ๊ฐ€์ ธ์˜ฌ ๋•Œ useRef๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. useRef๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ์œ„์— import React, { useState, useRef } from "react";์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•ด์ฃผ์„ธ์š”.
App ์ปดํฌ๋„ŒํŠธ ์•ˆ์— useRef๋ฅผ ์ƒ์„ฑํ•ด์ค๋‹ˆ๋‹ค.
const emailInput = useRef(null); // email input์— ๋Œ€ํ•œ useRef const pwInput = useRef(null); // pw input์— ๋Œ€ํ•œ useRef
src / App.js ์ปดํฌ๋„ŒํŠธ์— ์ฝ”๋“œ ์ถ”๊ฐ€ํ•˜๊ธฐ
ย 
์ƒ์„ฑํ•œ useRef ๊ฐ’์„ ๊ฐ’์„ ๋ฐ›์•„์˜ค๊ณ  ์‹ถ์€ ํƒœ๊ทธ์—๊ฒŒ ref props๋กœ ์ „๋‹ฌํ•ด์ค๋‹ˆ๋‹ค.
<label> ์ด๋ฉ”์ผ : <input type="email" ref={emailInput} /> </label> <label> ๋น„๋ฐ€๋ฒˆํ˜ธ : <input type="password" ref={pwInput} /> </label>
src / App.js์˜ return ๋ถ€๋ถ„์— ์žˆ๋Š” input ์ฝ”๋“œ ์ˆ˜์ •ํ•˜๊ธฐ
ย 
๋กœ๊ทธ์ธ๋ฒ„ํŠผ์„ ํด๋ฆญํ–ˆ์„ ๋•Œ ์‹คํ–‰ํ•  inputCheck์—์„œ emailInput๊ณผ pwInput์„ ์ถœ๋ ฅํ•ด๋ด…์‹œ๋‹ค.
notion imagenotion image
์ด์ œ useRef.current.value๋ฅผ ํ•˜๊ฒŒ๋˜๋ฉด inputํƒœ๊ทธ๋“ค์˜ ๊ฐ’๋“ค์„ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
email์™€ pw ๊ฐ’์„ useState๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์ƒํƒœ ๊ฐ’์„ ๋ฐ”๊ฟ”์ค๋‹ˆ๋‹ค.
const inputCheck = (e) => { e.preventDefault(); console.log(emailInput); console.log(pwInput); setEmailValue(emailInput.current.value); setPwValue(pwInput.current.value); };
src / App.js์˜ inputCheck ์ด๋ฒคํŠธ ๋‚ด๋ถ€ ์ฝ”๋“œ ์ˆ˜์ •ํ•˜๊ธฐ
ย 
import React, { useRef, useState } from "react"; const App = () => { const emailInput = useRef(null); // email input์— ๋Œ€ํ•œ useRef const pwInput = useRef(null); // pw input์— ๋Œ€ํ•œ useRef const [emailValue, setEmailValue] = useState(""); // email state ๊ฐ’ const [pwValue, setPwValue] = useState(""); // pw state ๊ฐ’ const inputCheck = (e) => { e.preventDefault(); setEmailValue(emailInput.current.value); setPwValue(pwInput.current.value); }; return ( <form style={{ display: "flex", flexDirection: "column" }}> <label> ์ด๋ฉ”์ผ : <input type="email" ref={emailInput} /> </label> <label> ๋น„๋ฐ€๋ฒˆํ˜ธ : <input type="password" ref={pwInput} /> </label> <button type="submit" style={{ width: "100px" }} onClick={inputCheck}> ํšŒ์›๊ฐ€์ž… </button> <span>{emailValue}</span> <span>{pwValue}</span> </form> ); }; export default App;
src / App.js ์™„์„ฑ์ฝ”๋“œ
ย 
ย 
  1. ์ด๋ฉ”์ผ input์ด๋‚˜ ๋น„๋ฐ€๋ฒˆํ˜ธ input์˜ ์ž…๋ ฅ์ด ์™„๋ฃŒ๋˜์ง€ ์•Š์€ ์ฑ„ ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด ์ž…๋ ฅ๋˜์ง€ ์•Š์€ input ํƒœ๊ทธ์— focusํ•ด๋ณด๋ก ํ•ฉ์‹œ๋‹ค.
ย 
useRef๊ฐ€ ๊ฐ€๋ฆฌํ‚ค๋Š” ํƒœ๊ทธ์— ์ด๋ฒคํŠธ๋ฅผ ์ค„ ๋•Œ๋Š” current ๋‹ค์Œ์— ์ด๋ฒคํŠธ๋ฅผ ์ž‘์„ฑํ•ด์ฃผ๋ฉด ๋ฉ๋‹ˆ๋‹ค. inputCheckํ•จ์ˆ˜ ์•ˆ์—์„œ ์ž‘์„ฑํ•ด์ฃผ์„ธ์š”.
if (emailInput.current.value === "") { alert("์ด๋ฉ”์ผ์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”"); emailInput.current.focus(); return; // if, else ๋ฌธ์— ๋“ค์–ด์˜ค๊ฒŒ ๋˜๋ฉด setState ์‹คํ–‰์—†์ด ๋ฐ”๋กœ return } else if (pwInput.current.value === "") { alert("๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”"); pwInput.current.focus(); return; }
src / App.js inputCheck์— ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•ด์ฃผ์„ธ์š”
ย 
import React, { useRef, useState } from "react"; const App = () => { const emailInput = useRef(null); // email input์— ๋Œ€ํ•œ useRef const pwInput = useRef(null); // pw input์— ๋Œ€ํ•œ useRef const [emailValue, setEmailValue] = useState(""); // email state ๊ฐ’ const [pwValue, setPwValue] = useState(""); // pw state ๊ฐ’ const inputCheck = (e) => { e.preventDefault(); if (emailInput.current.value === "") { alert("์ด๋ฉ”์ผ์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”"); emailInput.current.focus(); return; } else if (pwInput.current.value === "") { alert("๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”"); pwInput.current.focus(); return; } setEmailValue(emailInput.current.value); setPwValue(pwInput.current.value); }; return ( <form style={{ display: "flex", flexDirection: "column" }}> <label> ์ด๋ฉ”์ผ : <input type="email" ref={emailInput} /> </label> <label> ๋น„๋ฐ€๋ฒˆํ˜ธ : <input type="password" ref={pwInput} /> </label> <button type="submit" style={{ width: "100px" }} onClick={inputCheck}> ํšŒ์›๊ฐ€์ž… </button> <span>{emailValue}</span> <span>{pwValue}</span> </form> ); }; export default App;
src / App.js ์™„์„ฑ์ฝ”๋“œ
ย