ย
8.1 useRef๋?8.1.1 useRef์ ์ฌ์ฉ ๋ชฉ์ 8.2 useRef vs useState vs ์ผ๋ฐ๋ณ์8.2.1 useRef์ useState์ ์ฐจ์ด8.2.2 useRef ์ฌ์ฉํด๋ณด๊ธฐ8.3 useRef์ DOM8.3.1 useRef๋ก ํน์ ํ DOM ์ ํ8.3.2 useRef๋ก DOM ์ ํ ํ ์ฌ์ฉ ์ ์ฃผ์ ์ฌํญ8.4 (์ค์ต) useRef ์์ฉํด๋ณด๊ธฐ8.4.1 useRef๋ฅผ ์ฌ์ฉํ์ฌ focus ๊ด๋ฆฌํ๊ธฐ
8.1 useRef๋?
ย
const ref = useRef(initialValue);
ย
useRef์ ๊ธฐ๋ณธ ํํ์
๋๋ค. ํจ์ํ ์ปดํฌ๋ํธ์์ useRef๋ ์์ ์๋ฐ์คํฌ๋ฆฝํธ ๊ฐ์ฒด๋ฅผ ์์ฑํฉ๋๋ค. ์์ฑ๋ ๊ฐ์ฒด๋
{ current: initialValue }
์ ํํ๋ก ๋ฐํ์ด ๋๊ธฐ ๋๋ฌธ์ ref.current
์ ํํ๋ก ๊ฐ์ ์ ๊ทผ์ด ๊ฐ๋ฅํฉ๋๋ค. ๋ฐ๋ผ์ useRef๋ .current
ํ๋กํผํฐ์ ๋ณ๊ฒฝ ๊ฐ๋ฅํ ๊ฐ์ ๋ด๊ณ ์๋ โ์์โ์ ๊ฐ๋ค๊ณ ํํํ ์ ์์ต๋๋ค.ย
8.1.1 useRef์ ์ฌ์ฉ ๋ชฉ์
useRef๋ ํฌ๊ฒ 2๊ฐ์ง์ ๊ฒฝ์ฐ์ ์ฌ์ฉ์ด ๋ฉ๋๋ค.
- ํน์ DOM์ ์ ๊ทผํ์ฌ ์ ์ดํด์ผ ํ ๊ฒฝ์ฐ
- ๋ ๋๋ง๊ณผ ๊ด๊ณ์์ด ๊ฐ์ ๋ณ๊ฒฝํ๊ณ ์ถ์ ๊ฒฝ์ฐ
ย
์๋ฐ์คํฌ๋ฆฝํธ์ ๊ฒฝ์ฐ, getElementById, querySelector ๋ฑ์ ๋ฉ์๋๋ฅผ ํตํด ์ฝ๊ฒ DOM์ ์ ๊ทผํ์ฌ ์ ์ดํ ์ ์์ต๋๋ค. ํ์ง๋ง React์ ๊ฒฝ์ฐ์๋ ์ง์ DOM์ ์กฐ์ํ๋ ๊ฒ์ ๊ถ์ฅํ๊ณ ์์ง ์์ต๋๋ค. ๊ทธ๋ผ์๋ ๋ถ๊ตฌํ๊ณ ์คํฌ๋กค๋ฐ ์์น๋ฅผ ํ์
ํด์ผ ํ ๊ฒฝ์ฐ๋ input ์์์ ์๋ ํฌ์ปค์ค๋ฅผ ์ค์ ํด ์ฃผ์ด์ผ ํ ๊ฒฝ์ฐ์ฒ๋ผ ์ง์ DOM์ ์ ์ดํด ์ฃผ์ด์ผ ํ๋ ์์ธ์ ์ธ ์ํฉ์ด ๋ฐ์ํ ์ ์๋๋ฐ, ์ด๋ useRef๋ฅผ ์ฌ์ฉํด DOM์ ์ ๊ทผํ ์ ์์ต๋๋ค.
ย
React์์ DOM์ ์ง์ ์กฐ์์ ๊ถ์ฅํ์ง ์๋ ์ด์
React๋ Virtual DOM์ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ DOM ์กฐ์์ผ๋ก ์ธํ ๋ธ๋ผ์ฐ์ ๋ ๋๋ง์ ์ต์ํํ๋ค๋ ์ฅ์ ์ ๊ฐ์ง๊ณ ์์ต๋๋ค. ๋๋ฌธ์ ์ง์ DOM์ ์กฐ์ํ๊ฒ ๋๋ค๋ฉด โVirtual DOM์ ์ฌ์ฉํ ๋ธ๋ผ์ฐ์ ๋ ๋๋ง ์ต์ํโ ๋ผ๋ React์ ์ฅ์ ์ ๋์น๋ ์ผ์ด ๋ฐ์ํ๊ฒ ๋ฉ๋๋ค. ๋ฐ๋ผ์ ๊ฐ๋ฅํ๋ค๋ฉด ์ง์ DOM์ ์ ์ดํ๋ ๊ฒ์ ์ง์ํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
ย
๋ํ useRef๋ฅผ ์ฌ์ฉํ์ฌ ๋ฐํ๋ ๊ฐ์ฒด๋ ์ปดํฌ๋ํธ์ ์ ์์ ์ฃผ๊ธฐ๋ฅผ ํตํด ์ ์ง๋ฉ๋๋ค. ์ปดํฌ๋ํธ์ ์์ ์ฃผ๊ธฐ๋ DOM์ ๋ง์ดํธ๋๊ณ ์ธ๋ง์ดํธ๋๊ธฐ๊น์ง์ ๊ณผ์ ์ ๋งํฉ๋๋ค. useRef๋
.current
์ ๊ฐ์ด ๋ณ๊ฒฝ๋์ด๋ ์ปดํฌ๋ํธ ๋ฆฌ๋ ๋๋ง์ ๋ฐ์์ํค์ง ์๊ณ , ๋ ๋๋ง์ ํ ๋ ๋์ผํ ref ๊ฐ์ฒด๋ฅผ ์ ๊ณตํ๊ฒ ๋ฉ๋๋ค. ์ฆ, ์ปดํฌ๋ํธ๊ฐ ๊ณ์ํด์ ๋ ๋๋ง ๋๋๋ผ๋ ์ปดํฌ๋ํธ๊ฐ ์ธ๋ง์ดํธ๋๊ธฐ ์ ๊น์ง ๊ฐ์ด ๊ทธ๋๋ก ์ ์ง๋ฉ๋๋ค. ๋ฐ๋ผ์ ์ปดํฌ๋ํธ ๊ฐ์ ๋ณ๊ฒฝ์ ๊ด๋ฆฌํด์ผ ํ์ง๋ง ๋ฆฌ๋ ๋๋ง์ ๋ฐ์์ํฌ ํ์๋ ์์ ๋ ํ์ฉํ ์ ์์ต๋๋ค.ย
8.2 useRef vs useState vs ์ผ๋ฐ๋ณ์
ย
8.2.1 useRef์ useState์ ์ฐจ์ด
ย
useState ์ useRef ๋ ๋ชจ๋ ์ํ ๊ด๋ฆฌ๋ฅผ ์ํด ์ฌ์ฉํ ์ ์์ต๋๋ค. ๋ค๋ง useState ์ ๊ฒฝ์ฐ state ๊ฐ ๋ณ๊ฒฝ๋ ํ์ ๋ฆฌ๋ ๋๋ง์ ์งํํ๋ ๋ฐ๋ฉด, useRef ๋ ๋ฆฌ๋ ๋๋ง์ ์งํํ์ง ์์ต๋๋ค. useRef ๋ ๋ด๋ถ์ ์ผ๋ก ๊ฐ์ด ๋ณํ์ฌ ์ปดํฌ๋ํธ๊ฐ ๋ ๋๋ง ๋๊ธฐ ์ ๊น์ง๋ ๋ณ๊ฒฝ๋ ๊ฐ์ด ๋ณด์ด์ง ์๋ค๊ฐ ๋ ๋๋ง์ด ๋๋ ์์ ์ ๋ณ๊ฒฝ๋ ๊ฐ์ด ๋ณด์ด๊ฒ ๋ฉ๋๋ค. ์ด๋ฌํ ํน์ฑ์ ๋ง์ถ์ด ๋ ๋๋ง์ด ํ์ํ state ์ ๊ฒฝ์ฐ์๋ useState ๋ฅผ ์ฌ์ฉํ๋ ์ฉ๋์ ์์ ์ฃผ๊ธฐ ๋ด๋ด ๋ณํํ๋ ๊ฐ์ ๊ฐ๋ฆฌํค๊ณ ์๋ค๋ ์ฐจ๋ณ์ ์ ๊ฐ์ง๊ณ ์์ต๋๋ค.
ย
์ฆ, useState ๋ ์ปดํฌ๋ํธ์ ์์ ์ฃผ๊ธฐ์ ๋ฐ์ ํ ์ฐ๊ด์ด ์๋ ์์์ด๋ฏ๋ก ๋ ๋๋ง๊ณผ ๊ด๋ จ์ด ์๋ ๊ฐ์ ์ ์ฅํ๊ธฐ์๋ ์ ํฉํ์ง ์์ผ๋ฉฐ, useRef ๋ state ๋ ๋๋ง๊ณผ ๋ฌด๊ดํ ๊ฐ๊ณผ ์ด์ ์ ๊ฐ์ ์ ์ฅํ๊ธฐ์ ์ ํฉํ๋ค ํ ์ ์์ต๋๋ค. ๋ฐ๋ผ์ ๊ฐ๊ฐ์ ์ํฉ์ ๋ง๊ฒ Hook์ ์ ์ฌ์ฉํด์ผ ๋๊ฒ ์ต๋๋ค.
ย
8.2.2 useRef ์ฌ์ฉํด๋ณด๊ธฐ
ย
์๋ ์์ ๋ ๊ฐ ๋ฒํผ์ ๋๋ฅผ ๋๋ง๋ค +1 ์ฉ ์นด์ดํธ๊ฐ ๋๋ ์ฝ๋์
๋๋ค. ์ด๋ค ์ด์ ๋ก useRef ๋ฅผ ์ฌ์ฉํด์ผ ํ๋์ง ์์ ๋ฅผ ํตํด ํจ๊ป ์ดํด๋ณด๊ฒ ์ต๋๋ค.
ย
import { useRef, useState } from "react"; import "./styles.css"; export default function App() { const [stateCount, setStateCount] = useState(0); const refCount = useRef(0); return ( <div className="App"> <button onClick={() => { setStateCount((prev) => prev + 1); }} > State ๋ฒํผ </button> <button onClick={() => { refCount.current += 1; }} > Ref ๋ฒํผ </button> <br /> <br /> <div>useState Count: {stateCount}</div> <div>useRef Count: {refCount.current}</div> </div> ); }
ย
State ๋ฒํผ
์ ๋๋ฅด๋ฉด useState Count ๊ฐ์ด 1์ด ๋ ๊ฒ์ ํ์ธํ ์ ์์ง๋ง, Ref ๋ฒํผ
์ ๋๋ฅด๋ฉด useRef Count ๋ ๋ณ๊ฒฝ๋ ๊ฐ์ด ๋ ๋๋ง ๋์ง ์๊ณ ์์ต๋๋ค. ์ ๋ง๋ก useRef Count ๊ฐ์ ์นด์ดํธ๊ฐ ๋์ง ์๋ ๊ฒ์ผ๊น์? ๊ทธ๋ ์ง ์์ต๋๋ค. ๋ด๋ถ์ ์ผ๋ก๋ ์นด์ดํธ๊ฐ ์ฌ๋ผ๊ฐ๊ณ ์์ง๋ง ํ๋ฉด์ ๋ฐ๋ก ๋ ๋๋ง์ด ๋์ง ์์ ๋ฟ์
๋๋ค. ๋ค์ ํ ๋ฒ State ๋ฒํผ
์ ๋๋ฌ ๋ฆฌ๋ ๋๋ง์ ์ํค๊ฒ ๋๋ฉด useRef Count ๊ฐ๋ ์ฌ๋ผ๊ฐ๊ฒ ๋ฉ๋๋ค. state ๊ฐ ๋ณํ๋์ ๋, refCount.current
์ ๊ฐ๋ ๋ง์ฐฌ๊ฐ์ง๋ก ํ๋ฉด์ ๋ ๋๋ง ๋๋ ๊ฒ์์ ์ ์ ์์ต๋๋ค. ์ด์ ๋ useRef ๋ก ๋ถํฐ ์์ฑ๋ ๊ฐ์ฒด๋ useRef ๋ฅผ ํตํด ๋ฐํ๋ ๊ฐ์ฒด๋ component ์ ์์ ์ฃผ๊ธฐ ๋ด๋ด ๋ณํํ๋ ๊ฐ์ ๊ฐ๋ฆฌํค๊ณ ์๊ธฐ ๋๋ฌธ์ current ๊ฐ์ด ๋ณํํด๋ ๋ฆฌ๋ ๋๋ง์ ๊ด์ฌํ์ง ์๋๋ค๋ ๊ฒ์ ์๋ค๊ณ ๋ณผ ์ ์์ต๋๋ค.ย
8.3 useRef์ DOM
์์ ์ดํด๋ณธ useRef๋ฅผ ์ฌ์ฉํ๋ ์ด์ ์ค์๋ ํน์ DOM์ ์ ๊ทผํ์ฌ ์ ์ดํด์ผ ํ ๊ฒฝ์ฐ๊ฐ ์์์ต๋๋ค.
React์์ DOM์ ์ ํํ๊ธฐ ์ํด์๋
ref
๋ฅผ ์ฌ์ฉํ๋ฉด ๋๋๋ฐ, ref๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด์๋ useRef๋ผ๋ React์ Hook์ ์ฌ์ฉํฉ๋๋ค. ๊ฐ๋จํ ์ฝ๋๋ฅผ ํตํด DOM์ ์ ํํ๋ ๋ฐฉ๋ฒ์ ์์๋ด
์๋ค.8.3.1 useRef๋ก ํน์ ํ DOM ์ ํ
import React, { useRef } from "react"; function App() { const textInput = useRef(null); // --- โต useRef ์์ฑ const ClickBtn = () => { console.log("Click!"); }; const handleClickBtn = () => { textInput.current.focus(); // --- โท useRef๊ฐ ๊ฐ๋ฆฌํค๋ input ํ๊ทธ์ ํฌ์ปค์ค ์ด๋ฒคํธ ์ ์ฉ }; return ( <div> <input type="text" /> <input type="button" value="ref X" onClick={ClickBtn} /> <br /> <input type="text" ref={textInput} /> // --- โถ ref props๋ก ์ ๋ฌ <input type="button" value="ref O" onClick={handleClickBtn} /> </div> ); }; export default App;
ย
์ ์ฝ๋๋ useRef๋ฅผ ์ฌ์ฉํ์ฌ input์ ๊ฐ์ ๊ฐ์ ธ์จ ์์ ์ ๊ทธ๋ ์ง ์์ ์์ ๋ฅผ ๋น๊ตํ๊ธฐ ์ํ ์ฝ๋์
๋๋ค.
ย
ย
๋จผ์ , ์ฒซ ๋ฒ์งธ input์ onClick ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ์ ๊ฒฝ์ฐ ์ฝ์๋ง ์ฐํ ๋ฟ ๋ค๋ฅธ ๋ณํ๋ ์๊ธฐ์ง ์์ต๋๋ค. ํ์ง๋ง ๋ ๋ฒ์งธ input์ onClick ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ์ ๋ input ํ๊ทธ์ ํฌ์ปค์ค๊ฐ ์ ์ฉ๋๋๋ฐ ๋ค์๊ณผ ๊ฐ์ ํ๋ฆ์ผ๋ก ์ ์ฉ์ด ๋ฉ๋๋ค.
ย
import React, { useRef } from "react"; const textInput = useRef(null); // --- โต useRef ์์ฑ <input type="text" ref={textInput} /> // --- โถ ref props๋ก ์ ๋ฌ <input type="button" value="ref O" onClick={handleClickBtn} />
ย
useRef๋ฅผ ์์ฑํ๊ธฐ ์ํด react ๋ชจ๋์์ useRef๋ฅผ import ํด์จ ํ, text input์ ๋ํ useRef๋ฅผ ์์ฑํฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ ๊ฐ์ ๋ฐ์์ค๊ณ ์ถ์ input ํ๊ทธ์ ref props๋ก ์ ๋ฌํด์ค๋๋ค.
ย
const handleClickBtn = () => { textInput.current.focus(); // --- โท useRef๊ฐ ๊ฐ๋ฆฌํค๋ input ํ๊ทธ์ ํฌ์ปค์ค ์ด๋ฒคํธ ์ ์ฉ };
ย
๋ฒํผ์ ํด๋ฆญํ์ ๋, handleClickBtn ํจ์๊ฐ ์คํ๋๊ณ
textInput.current.focus
๋ฅผ ํตํด input ํ๊ทธ์ ํฌ์ปค์ค๋ฅผ ์ ์ฉํฉ๋๋ค.ย
ย
ย
๊ทธ๋ฌ๋ฉด ์์ ๊ฐ์ ๊ฒฐ๊ณผ๋ก ๋ฒํผ์ ํด๋ฆญํ์ ๋ input ํ๊ทธ์ ํฌ์ปค์ค๊ฐ ๋๋ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค.
ย
8.3.2 useRef๋ก DOM ์ ํ ํ ์ฌ์ฉ ์ ์ฃผ์ ์ฌํญ
useRef๋ฅผ ์ด์ฉํ์ฌ ์์ ์๋ฐ์คํฌ๋ฆฝํธ ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ณ ์ ํํ๊ณ ์ ํ๋ ํ๊ทธ์ ref props๋ฅผ ์ ๋ฌํ๋ฉด, ๊ทธ๋๋ถํฐ๋ ํด๋น ํ๊ทธ๊ฐ ์ ํ๋์ด ๋ค์ํ๊ฒ ํ์ฉ๋ ์ ์์์ input ํ๊ทธ ์์ ๋ฅผ ํตํด ํ์ธํด๋ณด์์ต๋๋ค. ๊ทธ๋ฐ๋ฐ ์ด DOM์ ์ธ์ ์ฌ์ฉํ๋๋์ ๋ฐ๋ผ ์ํ๋ ๊ฐ์ด ๋์ค๊ธฐ๋ ํ๊ณ
null
์ด๋ undefined
๊ฐ์ด ๋์ค๊ธฐ๋ ํฉ๋๋ค. ์ฝ๋๋ฅผ ํตํด ์ ํํ ์ธ์ ๊ทธ๋ฐ ์ํฉ์ด ๋ฐ์ํ๋์ง, ์ํ๋ ๋ฐ์ ๋ค๋ฅธ ๊ฒฐ๊ด๊ฐ์ด ๋์ค์ง ์๊ฒ ํ๊ธฐ ์ํด์๋ ์ด๋ป๊ฒ ์ฌ์ฉํด์ผ ํ ์ง ์์๋ณด๊ฒ ์ต๋๋ค. ย
import React, { useRef } from "react"; import music from "./assets/music.mp3"; function Player() { const audioRef = useRef(null); audioRef.current.play(); console.log(audioRef.current); const handlePlay = () => { audioRef.current.play(); console.log("๐ต์ฌ์๐ต"); }; const handlePause = () => { audioRef.current.pause(); console.log("โธ์ค์ง!"); }; return ( <> <audio src={music} ref={audioRef} controls></audio> <br /> <div style={{ margin: "10px 89px" }}> <button onClick={handlePlay}> ๐ต ์ฌ์ </button> <button onClick={handlePause}> โธ ์ค์ง </button> </div> </> ); } export default Player;
ย
์์ ์ฝ๋๋ ์ฌ์ ๋ฒํผ์ ๋๋ฅด๋ฉด ์ค๋์ค๊ฐ ์คํ๋๊ณ ์ค์ง ๋ฒํผ์ ๋๋ฅด๋ฉด ์ค๋์ค๊ฐ ์ค์ง๋๋ ํ๋ ์ด์ด ์์ ์
๋๋ค. ์ฌ๊ธฐ์ ๋ค์๊ณผ ๊ฐ์ด audio์ ๋ํ useRef๋ฅผ ์์ฑํ๊ณ ๋ฐ๋ก
ref.current
์ ํํ๋ก ์ค๋์ค์ ์ ๊ทผํด ๋ด
์๋ค.ย
const audioRef = useRef(null); audioRef.current.play(); console.log(audioRef.current); ... return ( <audio src={music} ref={audioRef} controls></audio> );
ย
ย
๊ฐ์ด ์ ์๋์ง ์์ ์๋ฌ๊ฐ ๋๊ณ ์์ต๋๋ค. ์ ๊ทธ๋ฐ ๊ฑธ๊น์? ์ฌ๊ธฐ์ ์ฐ๋ฆฌ๋ React์ ์ปดํฌ๋ํธ ๋ ๋๋ง ๊ณผ์ ์ ๋ํด ์ดํดํ๊ณ ์์ด์ผ ํฉ๋๋ค.
React์ ์ปดํฌ๋ํธ๊ฐ ์ต์ด ๋ ๋๋ง ๋์์ ๋๋ฅผ ์ผ๋ถ ์์ฝํ์ฌ ์ ๋ฆฌํ๋ฉด ๋ค์๊ณผ ๊ฐ์ ์์๋ฅผ ๋ฐ๋ฅด๊ฒ ๋ฉ๋๋ค.
- ํจ์ ์ปดํฌ๋ํธ๋ฅผ ํธ์ถํ๋ค.
- props, state ๋ฑ์ ๊ฐ์ ์ด๊ธฐํํ๋ค. (์ต์ด ๋ง์ดํธ ์ 1๋ฒ๋ง ์คํ)
- React DOM์ ๋ ๋๋งํ๋ค. (return ์คํ)
- ๊ธฐ์กด์ DOM์ ๋ฐ์ํ๋ค.
ย
ํ๋ ์ด์ด ์์ ์์๋ ์์ง React DOM์ ๋ ๋๋งํ์ง ์์๊ณ , ๊ธฐ์กด DOM์ ๋ฐ์๋์ง ์์ ์ฑ๋ก
ref.current
์ ํํ๋ก ์ฐธ์กฐ๋ฅผ ํ๋ ค๊ณ ํ๊ธฐ ๋๋ฌธ์ ์๋ฌ๊ฐ ๋ฐ์ํ๊ฒ ๋ฉ๋๋ค.ย
์ด๋ฌํ ํ์์ ๋ฐฉ์งํ๊ธฐ ์ํด์๋ React DOM์ ๋ ๋๋งํ๊ณ ๊ธฐ์กด์ DOM์ ๋ฐ์๋๊ณ ๋ ํ ์ฌ์ฉํ๊ฑฐ๋, ์กฐ๊ฑด๋ถ ๋ ๋๋ง์ ํตํด
ref.current
๊ฐ ์กด์ฌํ ๋์๋ง ์ฌ์ฉ์ด ๊ฐ๋ฅํ๋๋ก ํด์ผํฉ๋๋ค.ย
import React, { useEffect, useRef } from "react"; import music from "./assets/music.mp3"; function Player() { const audioRef = useRef(null); useEffect(() => { audioRef.current && audioRef.current.play(); // ์ ํจ์ฑ ๊ฒ์ฌ ํ ํ ์ฌ์ฉ }); const handlePlay = () => { audioRef.current.play(); console.log("๐ต์ฌ์๐ต"); }; const handlePause = () => { audioRef.current.pause(); console.log("โธ์ค์ง!"); }; return ( <> <audio src={music} ref={audioRef} controls></audio> <br /> <div style={{ margin: "10px 89px" }}> <button onClick={handlePlay}> ๐ต ์ฌ์ </button> <button onClick={handlePause}> โธ ์ค์ง </button> </div> </> ); } export default Player;
ย
audio ์์์ controls ์์ฑ
์ฌ์, ์ ์ง, ๋ณผ๋ฅจ ์กฐ์ ๊ณผ ๊ฐ์ ์ค๋์ค ๊ธฐ๋ณธ์ ์ธ ์ปจํธ๋กค๋ฌ ํ์ ์ฌ๋ถ๋ฅผ ๊ฒฐ์ ํ๋ ์์ฑ์
๋๋ค.
ย
8.4 (์ค์ต) useRef ์์ฉํด๋ณด๊ธฐ
ย
8.4.1 useRef๋ฅผ ์ฌ์ฉํ์ฌ focus ๊ด๋ฆฌํ๊ธฐ
ย
์ด๋ฒ ํํธ์์๋ useRef๋ฅผ ์ฌ์ฉํ์ฌ ํน์ input ์์๋ฅผ focus ํ ์ ์๋ ์ฝ๋๋ฅผ ์์ฑํด๋ณด๊ฒ ์ต๋๋ค.
์๋ ์์ ๋ค์ ํ์๊ฐ์
๋ฒํผ์ ๋๋ฅด๋ฉด ์
๋ ฅํ์ง ์์ input ์์๋ก ๋ฐ๋ก focus๋์ด, ์ฌ์ฉ์๊ฐ ๋๋ฝ๋ input ์์ ์์ด ์์ฑํ ์ ์๋๋ก ๋์ต๋๋ค.
ย
import React from "react"; function App() { return ( <form style={{ display: "flex", flexDirection: "column", alignItems: "center", gap: "10px", }} > <h2>ํ๋กํ ์ค์ </h2> <label> ์ด๋ฉ์ผ: <input type="email"></input> </label> <label> ๋น๋ฐ๋ฒํธ: <input type="password"></input> </label> <label> ๋น๋ฐ๋ฒํธ ํ์ธ: <input type="password"></input> </label> <label> ์ด๋ฆ: <input type="text"></input> </label> <label> ๋๋ค์: <input type="text"></input> </label> <button type="submit" style={{ width: "180px" }}> ํ์๊ฐ์ ํ๊ธฐ </button> </form> ); } export default App;
ย
form์์ onsubmit ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๋ฉด, input์์ ์
๋ ฅํ ๊ฐ์ ์ ๋ฌ๋ฐ์ต๋๋ค.
ํ์ง๋ง ์์ ์ฝ๋๋ง์ผ๋ก๋ input์์ ์
๋ ฅํ ๊ฐ์ ์ ๋ฌ๋ฐ์์ฌ ์ ์์ต๋๋ค. ๋ฐ๋ผ์ ์๋ ์ฝ๋์ ๊ฐ์ด useRef๋ฅผ ์ด์ฉํ์ฌ input์์ ์
๋ ฅํ ๊ฐ์ ์์ ์๋ฐ์คํฌ๋ฆฝํธ ๊ฐ์ฒด ํํ๋ก ๋ฐ์ ์ ์๋๋ก ํฉ๋๋ค. ์ฌ๊ธฐ์
inputRef
๋ ์๋ก์ด input ์์๊ฐ ์ถ๊ฐ๋์ด๋ ๋ฐฐ์ด๋ก์จ ์ฒ๋ฆฌ๊ฐ ๊ฐ๋ฅํ๋๋ก ๊ธฐ๋ณธ๊ฐ์ ๋น ๋ฐฐ์ด ํํ๋ก ์์ฑํ์ต๋๋ค.ย
import React, { useRef } from "react";
ย
const inputRef = useRef([]);
ย
React์์๋ ref๋ผ๋ ํ๋กํผํฐ๋ฅผ ํตํด ํน์ DOM ์์๋ฅผ ์ฐธ์กฐํ์ฌ ์
๋ ฅ๊ฐ์ ๋ฐ์ ์ ์์ต๋๋ค. ref๋ฅผ ์ด์ฉํ์ฌ ๊ฐ input ์์์์ ์
๋ ฅํ ๊ฐ์ ์ ๋ฌ๋ฐ์ ์๋์ ์ฝ๋์ฒ๋ผ
inputRef
๋ก ์ฐ๊ฒฐํด์ค๋๋ค.์๋ ์์ ๋ค์ ํ์๊ฐ์
๋ฒํผ์ ๋๋ฅด๋ฉด ์ด๋ ํ ๊ฐ๋ ์
๋ ฅ์ ํ์ง ์์ input ์์๋ก ๋ฐ๋ก focus๋์ด, ๋๋ฝ๋ input ์์ ์์ด ์ฌ์ฉ์๊ฐ ์์ฑํ ์ ์๋๋ก ๋์ต๋๋ค.์ค์ ํ ์ด๋ฆ์ผ๋ก ๋ณ๋๋๋ ๊ฐ์ฒด์ ๊ฐ์ ๋ฐ์ ์ ์์ต๋๋ค. ๊ฐ input ์์์์ ๋ณ๋๋๋ ๊ฐ์ ๋ฐ๋ ๋ณ์์ธ
inputRef
๋ฅผ ์ฐ๊ฒฐ์์ผ์ค๋๋ค.์ฌ๊ธฐ์,
inputRef
๋ ๊ฐ๊ฐ์ input ์์๋ก๋ถํฐ ์ ๋ฌ๋ฐ๋ ๊ฐ์ ๊ตฌ๋ถํ๊ธฐ ์ํด ["email"]
๋ ["pw"]
์ ๊ฐ์ด ๊ดํธ ํ๊ธฐ๋ฒ(bracket notation) ํํ๋ก ๊ณ ์ ํ ์ด๋ฆ์ ์์ฑํฉ๋๋ค.ย
// --- โ ์์ ์ ์ฝ๋ ์์ <label> ์ด๋ฉ์ผ: <input type="email"></input> </label> <label> ๋น๋ฐ๋ฒํธ: <input type="password"></input> </label> <label> ๋น๋ฐ๋ฒํธ ํ์ธ: <input type="password"></input> </label> <label> ์ด๋ฆ: <input type="text"></input> </label> <label> ๋๋ค์: <input type="text"></input> </label> // --- โก ์์ ํ ์ฝ๋ ์์ <label> ์ด๋ฉ์ผ: <input type="email" ref={(el)=>(inputRef.current["email"]=el)}></input> </label> <label> ๋น๋ฐ๋ฒํธ: <input type="password" ref={(el)=>(inputRef.current["pw"]=el)}></input> </label> <label> ๋น๋ฐ๋ฒํธ ํ์ธ: <input type="password" ref={(el)=>(inputRef.current["pwcheck"]=el)} ></input> </label> <label> ์ด๋ฆ:{" "} <input type="text" ref={(el)=>(inputRef.current["name"]=el)}></input> </label> <label> ๋๋ค์: <input type="text" ref={(el)=>(inputRef.current["nickname"]=el)}></input> </label>
ย
์์ ์ฝ๋๋ฅผ ๋ชจ๋ ์์ฑํ๋ค๋ฉด, ์๋ ์ฝ๋๋ฅผ ํตํด
inputRef
์ ๊ฒฐ๊ณผ๋ฅผ ํ์ธํด๋ณด๊ฒ ์ต๋๋ค.ย
console.log(inputRef);
ย
๊ทธ๋ฆผ 8-5์ฒ๋ผ
inputRef
์์๋ current๋ผ๋ ์ฐ๊ด๋ฐฐ์ด์ ๋๊ณ ์์ต๋๋ค. ๋ํ ์์์ ์
๋ ฅํ ๊ดํธ ํ๊ธฐ๋ฒ์ผ๋ก input ๊ฐ์ ์ ๊ทผ์ด ๊ฐ๋ฅํ๋ค๋ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค.ย
ย
์ฌ๊ธฐ์ ์ฐ๊ด๋ฐฐ์ด์ด๋ ๋ฐฐ์ด์ ํค(key)์ ๊ฐ(value)์ผ๋ก ๋๋์ด์ ์ฌ์ฉํ๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค.
ย
๋ง์ง๋ง์ผ๋ก ์ ์ถ์์์ ๋ฐ๋ผ ๊ฐ์ ์
๋ ฅํ๊ณ ์ ํ์๊ฐ์
ํ๊ธฐ ๋ฒํผ์ ํด๋ฆญํ์ฌ ์ ์ถํ์ ๋, input ์์์ ์
๋ ฅ๊ฐ์ด ๋๋ฝ๋์๋ค๋ฉด, ํด๋น input ์์์ focus๊ฐ ๋๋
inputCheck
ํจ์๋ฅผ ์ถ๊ฐํฉ๋๋ค.ย
const inputCheck = (e) => { e.preventDefault(); if (inputRef.current["email"].value === "") { console.log("์ด๋ฉ์ผ์ ์ ๋ ฅํด์ฃผ์ธ์"); inputRef.current["email"].focus(); return; } else if (inputRef.current["pw"].value === "") { console.log("๋น๋ฐ๋ฒํธ๋ฅผ ์ ๋ ฅํด์ฃผ์ธ์"); inputRef.current["pw"].focus(); return; } else if (inputRef.current["pwcheck"].value === "") { console.log("๋น๋ฐ๋ฒํธ ํ์ธ์ ์ ๋ ฅํด์ฃผ์ธ์"); inputRef.current["pwcheck"].focus(); return; } else if (inputRef.current["name"].value === "") { console.log("์ด๋ฆ์ ์ ๋ ฅํด์ฃผ์ธ์"); inputRef.current["name"].focus(); return; } else if (inputRef.current["nickname"].value === "") { console.log("๋๋ค์์ ์ ๋ ฅํด์ฃผ์ธ์"); inputRef.current["nickname"].focus(); return; } };
ย
๊ทธ๋ฆฌ๊ณ form์์ onsubmit ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ ๋,
inputCheck
๊ฐ ์คํ๋๋๋ก ์๋์ ์ฝ๋๋ก ์์ ํฉ๋๋ค.ย
<form style={{ display: "flex", flexDirection: "column", alignItems: "center", gap: "10px", }} onSubmit={inputCheck} >
ย
๊ทธ๋ฆผ 8-6์ ์ด๋ฉ์ผ๊ณผ ๋น๋ฐ๋ฒํธ ๊ทธ๋ฆฌ๊ณ ์ด๋ฆ์ด ์
๋ ฅ๋ ์ํ์
๋๋ค. ํ์ง๋ง ๋น๋ฐ๋ฒํธ ํ์ธ๊ณผ ๋๋ค์์ ์์ฑํ์ง ์์ ์ํ์ด๊ธฐ ๋๋ฌธ์ ์ด๋ ํ์๊ฐ์
ํ๊ธฐ ๋ฒํผ์ ๋๋ฅด๋ฉด, ๊ทธ๋ฆผ 8-7์ฒ๋ผ input ๊ฐ์ด ๋น ์ง ๋น๋ฐ๋ฒํธ ํ์ธ๊ณผ ๋๋ค์ ์ค ์ฝ๋์์ ๋จผ์ ์ ์ธ๋ ๋น๋ฐ๋ฒํธ ํ์ธ์์ focus๊ฐ ๋๋ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค.
ย
ย
import React, { useRef } from "react"; function App() { const inputRef = useRef([]); const inputCheck = (e) => { e.preventDefault(); if (inputRef.current["email"].value === "") { console.log("์ด๋ฉ์ผ์ ์ ๋ ฅํด์ฃผ์ธ์"); inputRef.current["email"].focus(); return; } else if (inputRef.current["pw"].value === "") { console.log("๋น๋ฐ๋ฒํธ๋ฅผ ์ ๋ ฅํด์ฃผ์ธ์"); inputRef.current["pw"].focus(); return; } else if (inputRef.current["pwcheck"].value === "") { console.log("๋น๋ฐ๋ฒํธ ํ์ธ์ ์ ๋ ฅํด์ฃผ์ธ์"); inputRef.current["pwcheck"].focus(); return; } else if (inputRef.current["name"].value === "") { console.log("์ด๋ฆ์ ์ ๋ ฅํด์ฃผ์ธ์"); inputRef.current["name"].focus(); return; } else if (inputRef.current["nickname"].value === "") { console.log("๋๋ค์์ ์ ๋ ฅํด์ฃผ์ธ์"); inputRef.current["nickname"].focus(); return; } }; return ( <form style={{ display: "flex", flexDirection: "column", alignItems: "center", gap: "10px", }} onSubmit={inputCheck} > <h2>ํ๋กํ ์ค์ </h2> <label> ์ด๋ฉ์ผ: <input type="email" ref={(el)=>(inputRef.current["email"]=el)}></input> </label> <label> ๋น๋ฐ๋ฒํธ: <input type="password" ref={(el)=>(inputRef.current["pw"]=el)}></input> </label> <label> ๋น๋ฐ๋ฒํธ ํ์ธ: <input type="password" ref={(el)=>(inputRef.current["pwcheck"]=el)} ></input> </label> <label> ์ด๋ฆ:{" "} <input type="text" ref={(el)=>(inputRef.current["name"]=el)}></input> </label> <label> ๋๋ค์: <input type="text" ref={(el)=>(inputRef.current["nickname"]=el)}></input> </label> <button type="submit" style={{ width: "180px" }}>ํ์๊ฐ์ ํ๊ธฐ</button> </form> ); } export default App;
ย