ย
9.1 useImperativeHandle์ด๋?9.1.1 ๊ธฐ๋ณธ ๊ตฌ์กฐ9.1.2 ์ฌ์ฉ์ ์ฃผ์์ 9.2 ๊ธฐ๋ณธ ์ฌ์ฉ๋ฒ9.2.1 React.forwardRef9.2.2 useImperativeHandle ์ฌ์ฉํ๊ธฐ9.3 ์ค์ฉ ์์ 9.3.1 useImperativeHandle์ ์ฌ์ฉํ์ง ์์ ์ค์ฉ ์์ 9.3.2 useImperativeHandle์ ์ฌ์ฉํ ์ค์ฉ ์์
ย
9.1 useImperativeHandle์ด๋?
useImperativeHandle์ ํํ ์ฌ์ฉ๋์ง๋ ์์ง๋ง ๋ถ๋ชจ ์ปดํฌ๋ํธ๊ฐ ์์ ์ปดํฌ๋ํธ์ ํจ์๋ฅผ ํธ์ถํ๊ฑฐ๋ ๋ถ๋ชจ ์ปดํฌ๋ํธ์์ ์์ ์ปดํฌ๋ํธ์ ์ํ ๊ฐ์ ๋ณ๊ฒฝํ๊ณ ์ถ์ ๋ ์ฌ์ฉ๋๋ Hook์
๋๋ค. useImperativeHandle์ ref๋ฅผ ์ฌ์ฉํ ๋ ๋ถ๋ชจ ์ปดํฌ๋ํธ์ ๋
ธ์ถ๋๋ ์ธ์คํด์ค ๊ฐ์ ์ปค์คํฐ๋ง์ด์งํ ์ ์์ต๋๋ค. ์ด Hook์ ํญ์ ref์ ํจ๊ป ์ฌ์ฉํด์ผ ํ๊ณ ๊ณต์ ๋ฌธ์์์๋ React.forwardRef์ ํจ๊ป ์ฌ์ฉํ๊ฒ๋ ๊ธฐ์ฌ๋์ด ์์ต๋๋ค.
ย
9.1.1 ๊ธฐ๋ณธ ๊ตฌ์กฐ
ย
useImperativeHandle(ref, createHandle, [deps])
ย
useImperativeHandle์ ์์ ๊ฐ์ด ์ธ ๊ฐ์ ์ธ์๋ฅผ ๋ฐ์ ์ ์์ต๋๋ค. ์ฒซ ๋ฒ์งธ ์ธ์๋ ํ๋กํผํฐ๋ฅผ ๋ถ์ฌํ ref์
๋๋ค. ๋ณดํต forwardRef( ) ํจ์๋ก ๋ถ๋ชจ์๊ฒ์ ๋ฐ์์จ ref๋ฅผ ํ ๋นํฉ๋๋ค. ๋ ๋ฒ์งธ ์ธ์๋ createHandle๋ก ๊ฐ์ฒด๋ฅผ ๋ฆฌํดํ๋ ํจ์๋ฅผ ํ ๋นํฉ๋๋ค. ํด๋น ๊ฐ์ฒด์๋ ์ถ๊ฐํ๊ณ ์ถ์ ํ๋กํผํฐ๋ฅผ ์ ์ํ ์ ์์ต๋๋ค. ์ธ ๋ฒ์งธ ์ธ์๋ ์์กด์ฑ ๋ฐฐ์ด๋ก ํ์๊ฐ ์๋ ์ ํ์ ์ธ์์ด๋ฉฐ Hook์ด ์ฌ์ ์๋์ด์ผ ํ๋ ์กฐ๊ฑด๋ค์ ํ ๋นํฉ๋๋ค.
ย
9.1.2 ์ฌ์ฉ์ ์ฃผ์์
useImperativeHandle์ ์์ ์ปดํฌ๋ํธ๊ฐ ์ฃผ์ํ ์ํ๋ ๋ก์ง์ ๊ฐ์ง๊ณ ์๋ ๊ฒฝ์ฐ์ ์ ์ฉํ๊ฒ ์ฌ์ฉํ ์ ์๋ Hook์
๋๋ค.
๋๋ถ๋ถ์ ๊ฒฝ์ฐ ref๋ฅผ ์ฌ์ฉํ ๋ช ๋ นํ ์ฝ๋๋ ํผํด์ผ ํฉ๋๋ค.ย
ํ์ง๋ง ๊ณต์ ๋ฌธ์์ ๊ธฐ์ฌ๋์ด ์๋ฏ์ด '๋ฌด์'์ ํ ๊ฒ์ธ๊ฐ? ์ ์ด์ ์ ๋ง์ถ ์ ์ธํ ํ๋ก๊ทธ๋๋ฐ์ธ React๋ ์ ์ธ์ ์ผ๋ก ํด๊ฒฐ๋ ์ ์๋ ๋ฌธ์ (state๋ prop์ ์ฌ์ฉํด์ ํด๊ฒฐ๋ ์ ์๋ ๋ฌธ์ )์์๋ ๋ฌด์์ '์ด๋ป๊ฒ' ํ ๊ฒ์ธ๊ฐ?์ ์ด์ ์ ๋ง์ถ ๋ช
๋ นํ ํ๋ก๊ทธ๋๋ฐ์ธ ref๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ ๊ถ์ฅํ์ง ์์ต๋๋ค.
๋ฐ๋ผ์ useImperativeHandle Hook์ ํ์ํ ๊ณณ์์๋ง ์ ๋ณ์ ์ผ๋ก ์ฌ์ฉํด์ผ ํฉ๋๋ค.
ย
9.2 ๊ธฐ๋ณธ ์ฌ์ฉ๋ฒ
์ด์ useImperativeHandle์ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ ์์๋ณด๊ฒ ์ต๋๋ค. ๊ธฐ๋ณธ์ ์ผ๋ก useImperativeHandle์ React.forwardRef์ ํจ๊ป ์ฌ์ฉ๋ฉ๋๋ค. ๋จผ์ React.forwardRef์ ๋ํด ๊ฐ๋จํ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
ย
9.2.1 React.forwardRef
React.forwardRef๋ ๋ถ๋ชจ ์ปดํฌ๋ํธ๊ฐ ์์ ์ปดํฌ๋ํธ์๊ฒ ref๋ฅผ ์ ๋ฌํ ๋ ์ฌ์ฉํ๋ ๊ธฐ์ ์
๋๋ค. ๋ถ๋ชจ ์ปดํฌ๋ํธ๊ฐ ์์ ์ปดํฌ๋ํธ์ DOM ๋
ธ๋์ ์ง์ ์ ๊ทผํด์ผ ํ ๋ ํนํ ์ ์ฉํ๊ฒ ์ฌ์ฉ๋ฉ๋๋ค. React ์ปดํฌ๋ํธ์์ย ref๋ฅผ prop์ผ๋ก ์ ๋ฌํ๊ธฐ ์ํด์๋ React.forwardRef๋ฅผ ์ฌ์ฉํด์ผ ํฉ๋๋ค.
ย
๊ฐ๋จํ ์์ ๋ก React.forwardRef๋ฅผ ์ฌ์ฉํด๋ณด๊ฒ ์ต๋๋ค. ๊ทธ๋ฆผ 9-1๊ณผ ๊ฐ์ด ๋ฒํผ์ ํด๋ฆญํ ๋
MyInput
์ด๋ผ๋ Input ์ปดํฌ๋ํธ์ ํฌ์ปค์ค๋ฅผ ์ฃผ๋ ์์ ์
๋๋ค. ย
ย
๋จผ์ ๋ถ๋ชจ ์ปดํฌ๋ํธ์ธ
App
์ปดํฌ๋ํธ์ useRef๋ฅผ ์ด์ฉํด์ ref๋ฅผ ๋ง๋ค๊ณ ๊ทธ๊ฒ์ ์ ๋ฌํ๊ธฐ ์ํด MyInput
์ ref ์์ฑ์ผ๋ก ๋ฃ์ด์ฃผ์์ต๋๋ค. ย
import React, { useRef } from 'react'; import MyInput from './MyInput'; function App() { const inputRef = useRef(); const focus = () => { inputRef.current.focus(); }; return ( <div style={{ margin: '20px 10px' }}> <MyInput ref={inputRef} /> <button style={{ marginLeft: '10px' }} onClick={focus}>์ธํ ํฌ์ปค์ค</button> </div> ); }; export default App;
ย
ref๋ฅผ ์ ๋ฌ๋ฐ์ ์์ ์ปดํฌ๋ํธ๋ฅผ forwardRef() ํจ์๋ก ๊ฐ์ธ์ฃผ๋ฉด ์์ ์ปดํฌ๋ํธ๋ ๋ ๋ฒ์งธ ๋งค๊ฐ๋ณ์๋ฅผ ๊ฐ๊ฒ ๋๋๋ฐ, ์ฌ๊ธฐ์ ๋ถ๋ชจ์๊ฒ์ ์ ๋ฌ๋ฐ์ ref๊ฐ ๋ค์ด์์ต๋๋ค. ์์ ์ปดํฌ๋ํธ๋ ์ ๋ฌ๋ฐ์ ref๋ฅผ input ํ๊ทธ์ ref ์์ฑ์ผ๋ก ๋ฃ์ด์ฃผ๋ฉด ๋ฉ๋๋ค. ์ด์ ref๋ input์ DOM ๋
ธ๋๋ฅผ ์ฐธ์กฐํ๊ฒ ๋์ด ๋ฒํผ์ด ํด๋ฆญ๋ ๋๋ง๋ค focus() ํจ์๋ฅผ ํธ์ถํ ์ ์๊ฒ ๋ฉ๋๋ค.
ย
import { forwardRef } from 'react'; function MyInput(props, ref) { return <input ref={ref} />; }; export default forwardRef(MyInput);
ย
์์ ๊ฐ์ด React.forwardRef๋ฅผ ์ฌ์ฉํ๋ฉด HTML ์๋ฆฌ๋จผํธ์ ref๋ฅผ ์ ๋ฌํ๋ฏ ๋ถ๋ชจ ์ปดํฌ๋ํธ๊ฐ ์์ ์ปดํฌ๋ํธ์๊ฒ ref๋ฅผ ์ ๋ฌํ ์ ์๊ฒ ๋ฉ๋๋ค. ์ผ๋ฐ์ ์ผ๋ก forwardRef() ํจ์๋ ์ ํ๋ฆฌ์ผ์ด์
์ ์ฒด์ ์ผ๋ก ์ฌ์ฌ์ฉ์ฑ์ด ๋์ ์ตํ์ ์ปดํฌ๋ํธ๋ฅผ ๋์์ผ๋ก ์ฃผ๋ก ์ฌ์ฉ๋๋ฉฐ, ๊ทธ๋ณด๋ค ์์ ์ปดํฌ๋ํธ์์ ์ฌ์ฉํ๋ ๊ฒ์ ๊ถ์ฅ๋์ง ์์ต๋๋ค.
ย
9.2.2 useImperativeHandle ์ฌ์ฉํ๊ธฐ
์ด์ useImperativeHandle์ React.forwardRef์ ํจ๊ป ์ฌ์ฉํด๋ณด๊ฒ ์ต๋๋ค. useImperativeHandle์ ์ฌ์ฉํ๋ ์ปดํฌ๋ํธ๋ React.forwardRef๋ก ๊ฐ์ธ์ฃผ์ด์ผ ํฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ ๋ถ๋ชจ ์ปดํฌ๋ํธ๋ก๋ถํฐ React.forwardRef์ ๋ ๋ฒ์งธ ๋งค๊ฐ๋ณ์๋ก ์ ๋ฌ๋ฐ์ ref๋ฅผ useImperativeHandle์ ์ฒซ ๋ฒ์งธ ์ธ์ ๊ฐ์ผ๋ก ์ ๋ฌํฉ๋๋ค.
ย
์์ ์์ ์ ๋น์ทํ๊ฒ ๋ฒํผ์ ํด๋ฆญํ ๋
MyInput
์ด๋ผ๋ Input ์ปดํฌ๋ํธ์ ํฌ์ปค์ค๋ฅผ ์ฃผ๋ฉด์ ๋์์ input ํ๊ทธ์ value๋ฅผ ํฌ์ปค์ค ๋์์ต๋๋ค!
๋ผ๊ณ ๋ณ๊ฒฝํ๋ ์์ ๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค. ๊ทธ๋ฆผ 9-2๋ ์์ ์ฝ๋์ ์คํ ๊ฒฐ๊ณผ์
๋๋ค.ย
ย
์์ ์ปดํฌ๋ํธ์ธ
MyInput
๋ฅผ ๋ณด๋ฉด, forwardRef() ํจ์๋ก ๊ฐ์ธ์ฌ ์๊ณ ๋ ๋ฒ์งธ ๋งค๊ฐ๋ณ์์ธ ref๊ฐ useImperativeHandle์ ์ฒซ ๋ฒ์งธ ์ธ์๋ก ๋ค์ด๊ฐ ์๋ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค.ย
import { forwardRef, useImperativeHandle, useRef } from 'react'; function MyInput(props, ref) { const inputRef = useRef(); useImperativeHandle(ref, () => ({ customFocus: () => { inputRef.current.focus(); inputRef.current.value = 'ํฌ์ปค์ค ๋์์ต๋๋ค!'; }, })); return <input ref={inputRef} />; } export default forwardRef(MyInput);
ย
useImperativeHandle์ ๋ ๋ฒ์งธ ์ธ์์๋
customFocus
๋ผ๋ ๋ฉ์๋๋ฅผ ์ ์ํ๊ณ , ์ฌ์ฉํ๊ณ ์ถ์ ๊ณณ์์ inputRef.current์ customFocus
๋ฅผ ํธ์ถํด์ ์ฌ์ฉํ ์ ์์ต๋๋ค.ย
import React, { useRef } from 'react'; import MyInput from './MyInput'; function App() { const inputRef = useRef(); return ( <div style={{ margin: '20px 10px' }}> <MyInput ref={inputRef} /> <button style={{ marginLeft: '10px' }} onClick={() => inputRef.current.customFocus()} > ์ธํ ํฌ์ปค์ค </button> </div> ); } export default App;
ย
๊ธฐ์กด์ input ์๋ฆฌ๋จผํธ์๋
customFocus
๋ผ๋ ๋ฉ์๋๊ฐ ์์ง๋ง,ย useImperativeHandle์์ ์ ์ํ๊ธฐ ๋๋ฌธ์ ์ฌ์ฉํ ์ ์์ต๋๋ค. ์ด์ฒ๋ผ useImperativeHandle Hook์ ์ด์ฉํ๋ฉด, ์์ ์ปดํฌ๋ํธ์์ ์ปค์คํฐ๋ง์ด์งํ ๋ฉ์๋๋ฅผ ๋ถ๋ชจ ์ปดํฌ๋ํธ์์ ์ฌ์ฉํ ์ ์๊ฒ ๋ฉ๋๋ค.ย
9.3 ์ค์ฉ ์์
9.3.1 useImperativeHandle์ ์ฌ์ฉํ์ง ์์ ์ค์ฉ ์์
useImperativeHandle์ ์ค์ฉ ์์ ๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค. ์๋ ๊ทธ๋ฆผ 9-3์ ์ค์ฉ ์์ ์ ์์ฑ๋ณธ์
๋๋ค. ์ค์ฉ ์์ ๋ ๋ฒํผ์ ํด๋ฆญํ๋ฉด CSS ๋ฐ์ค ์์์ ๋ณ๊ฒฝํ ์ ์๋ ์ ํ๋ฆฌ์ผ์ด์
์
๋๋ค. useImperativeHandle Hook์ ์ฌ์ฉํ ์์ ์ ์ฌ์ฉํ์ง ์์ ์์ ๋ฅผ ๋น๊ตํ์ฌ Hook์ ๋ํด ๋ ์์ธํ ๋ค๋ค๋ณด๊ฒ ์ต๋๋ค.
ย
ย
์ฐ์ ์ useImperativeHandle Hook์ ์ฌ์ฉํ์ง ์์ ์์ ๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
ย
import { useState } from "react"; import CustomModal from "./CustomModal"; function App() { const [open, setOpen] = useState(false); const [isTomato, setIsTomdato] = useState(false); const [isPink, setIsPink] = useState(false); const [isSky, setIsSky] = useState(false); return ( <> <button onClick={() => setOpen(true)}>Open</button> <button onClick={() => { setIsPink(true); }} > Pink Btn </button> <button onClick={() => { setIsSky(true); }} > Skyblue Btn </button> <button onClick={() => { setIsTomdato(true); }} > Tomato Btn </button> <CustomModal isOpen={open} onClose={() => { setOpen(false); setIsPink(false); setIsSky(false); setIsTomdato(false); }} isPink={isPink} isSky={isSky} isTomato={isTomato} /> </> ); } export default App;
ย
์์ ์ปดํฌ๋ํธ์ DOM ๋
ธ๋์ ์ง์ ์ ๊ทผ์ด ๋ถ๊ฐ๋ฅํ๋, ์ํ ๊ฐ์ ์์ฑํ์ฌ ์์ ์ปดํฌ๋ํธ์ props ๊ฐ์ผ๋ก ๋๊ฒจ์ค๋๋ค. ๊ฐ div ํ๊ทธ์ ์์์ ๊ฒฐ์ ํ๊ธฐ ์ํ ์ธ ๊ฐ์ ์ํ ๊ฐ, ๋ชจ๋ฌ์ ์ฌ๋ซ์ ํ๋์ ์ํ ๊ฐ์ ์์ฑํ์ฌ ์ ๋ฌํฉ๋๋ค.
ย
import React, { useRef } from "react"; import { useEffect } from "react"; const CustomModal = ({ isOpen, onClose, isPink, isSky, isTomato }) => { const closeRef = useRef(); const pinkRef = useRef(); const skyblueRef = useRef(); const tomatoRef = useRef(); useEffect(() => { if (isPink) { pinkRef.current.style = "width:50px; height:50px; background:pink;"; } if (isSky) { skyblueRef.current.style = "width:50px; height:50px; background:skyblue;"; } if (isTomato) { tomatoRef.current.style = "width:50px; height:50px; background:tomato;"; } }, [isPink, isSky, isTomato]); if (!isOpen) return null; return ( <div> <br /> <button ref={closeRef} onClick={onClose}> × </button> <h1>Color Change</h1> <div> <div ref={pinkRef}>color1</div> <div ref={skyblueRef}>color2</div> <div ref={tomatoRef}>color3</div> </div> </div> ); }; export default CustomModal;
ย
CustomModal
์ปดํฌ๋ํธ์์๋ ๊ฐ div ํ๊ทธ์ ์ ๊ทผํ๊ธฐ ์ํ Ref๋ฅผ ์์ฑํด์ค๋๋ค. props๋ก ๋๊ฒจ๋ฐ์ ๊ฐ ์ํ ๊ฐ์ด true๋ก ๋ฐ๋ ๊ฒฝ์ฐ, Ref๋ฅผ ํตํด ํด๋น DOM ๋
ธ๋์ ์ ๊ทผํ์ฌ ์คํ์ผ์ ๋ฐ๊ฟ์ค๋๋ค.ย
์ ์ฝ๋๋ ๋ถ๋ชจ ์ปดํฌ๋ํธ์์ useState๋ฅผ ๋ด๋ ค์ฃผ์ด ์์ ์ปดํฌ๋ํธ ์์์ ํน์ ํ๊ทธ์ ์ํฅ์ ์ฃผ๋ ๋ฐฉ๋ฒ์
๋๋ค. ํ์ง๋ง ๋ค์์ ๋์ฌ ์์ ์ฒ๋ผ useImperativeHandle์ ์ฌ์ฉํ๋ค๋ฉด, ๋ถ๋ชจ์์ ์ง์ ์์ ์ปดํฌ๋ํธ์ ํ๊ทธ์ ์ ๊ทผํ ์ ์์ต๋๋ค.
ย
9.3.2 useImperativeHandle์ ์ฌ์ฉํ ์ค์ฉ ์์
useImperativeHandle Hook์ ์ฌ์ฉํ์ฌ ์์ ๋ง๋ ์ค์ฉ ์์ ์ ๊ฐ์ ์ ํ๋ฆฌ์ผ์ด์
์ ๋ง๋ค์ด๋ณด๊ฒ ์ต๋๋ค.
ย
import { useState, useRef } from "react"; import CustomModal from "./CustomModal"; function App() { const [open, setOpen] = useState(false); const modalRef = useRef(); return ( <> <button onClick={() => setOpen(true)}>Open</button> <button onClick={() => { //์์ ๋ด์ฉ }} > Pink Btn </button> <CustomModal ref={modalRef} open={open} onClose={() => setOpen(false)} /> </> ); } export default App;
ย
๋จผ์ App.js์์ Open ๋ฒํผ๊ณผ Pink Btn ๋ฒํผ์ ๋ง๋ค์์ต๋๋ค. Open ๋ฒํผ์ ํด๋ฆญํ๋ฉด Color Change ๋ชจ๋ฌ์ด ๋ํ๋๊ณ Pink Btn ๋ฒํผ์ ํด๋ฆญํ๋ฉด โcolor1โ ํ
์คํธ์ ๋ฐฐ๊ฒฝ์์ด ๋ถํ์์ผ๋ก ๋ณ๊ฒฝ๋ฉ๋๋ค. ํด๋น ๊ธฐ๋ฅ์ ๋ชจ๋ฌ์ ํด๋นํ๋
CustomModal
์ปดํฌ๋ํธ์์ useImperativeHandle Hook์ ํ์ฉํด ๊ตฌํํ๊ฒ ์ต๋๋ค. ย
useImperativeHandle Hook์ ์ฌ์ฉํ๊ธฐ ์ํด
CustomModal
์ปดํฌ๋ํธ์ modalRef
๋ฅผ prop์ผ๋ก ์ ๋ฌํด์ฃผ์์ต๋๋ค. ์๋ ๊ทธ๋ฆผ 9-4๋ Open ๋ฒํผ์ ํด๋ฆญํ์ฌ ๋ชจ๋ฌ์ ๋์ด ์ํ์
๋๋ค.ย
ย
import React from "react"; import { useRef } from "react"; function CustomModal({ open, onClose }, ref) { const closeRef = useRef(); const pinkRef = useRef(); if (!open) return null; return ( <div> <br /> <button ref={closeRef} onClick={onClose}> × </button> <h1>Color Change</h1> <div> <div ref={pinkRef}>color1</div> </div> </div> ); } export default React.forwardRef(CustomModal);
ย
CustomModal
์ปดํฌ๋ํธ๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค. useRef Hook์ ํตํด closeRef์ pinkRef๋ผ๋ ref ๊ฐ์ฒด๋ฅผ ๋ง๋ญ๋๋ค. ๋ ๊ฐ์ง ref ๊ฐ์ฒด๋ฅผ ๊ฐ๊ฐ ๋ชจ๋ฌ์ ๋ซ๊ธฐ ๋ฒํผ๊ณผ โcolor1โ ํ
์คํธ์ ref ๊ฐ์ผ๋ก ์ค์ ํฉ๋๋ค. ์ด๋ ๋ซ๊ธฐ ๋ฒํผ๊ณผ โcolor1โ ํ
์คํธ์ DOM ๋
ธ๋๋ฅผ ๊ฐ๋ฆฌ์ผ ์ํ๋ ๋ฐฉ์์ผ๋ก ์กฐ์ํ๊ธฐ ์ํ ๋ชฉ์ ์
๋๋ค. ย
useImperativeHandle(ref, () => { return { closeBtn: closeRef.current, pinkBtn: pinkRef.current, }; });
ย
์ดํ useImperativeHandle Hook์ ์ธ์๋ก App.js์์ ์ ๋ฌํด์จ prop์ธ ref๋ฅผ ๋ฐ์ต๋๋ค. ๊ทธ ๋ค์ ์ฝ๋ฐฑํจ์๋ก closeBtn๊ณผ pinkBtn์ ๋ฐํํ๋ฉด ๋ถ๋ชจ ์ปดํฌ๋ํธ์ธ App.js์์๋ ํด๋น ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค. closeBtn์ closeRef.current์ ํ ๋นํ์ฌ ๋ซ๊ธฐ ๋ฒํผ DOM ๋
ธ๋๋ฅผ ๊ฐ๋ฆฌํฌ ์ ์๊ฒ ํ๊ณ , pinkBtn์๋ pinkRef.current ์ ๋ฃ์ด โcolor1โ ํ
์คํธ์ div ํ๊ทธ๋ฅผ ๊ฐ๋ฆฌํฌ ์ ์๊ฒ ํฉ๋๋ค. ์ด๋ฅผ ํตํด App.js์์ closeBtn๊ณผ pinkBtn์ ํ์ฉํ์ฌ ๋ชจ๋ฌ ๋ซ๊ธฐ ๊ธฐ๋ฅ๊ณผ ๋ฐฐ๊ฒฝ์ ๋ณ๊ฒฝ ๊ธฐ๋ฅ์ ๊ตฌํํ ์ค๋น๊ฐ ๋์์ต๋๋ค.
ย
import React from "react"; import { useRef, useImperativeHandle } from "react"; function CustomModal({ open, onClose }, ref) { const closeRef = useRef(); const pinkRef = useRef(); useImperativeHandle(ref, () => { return { closeBtn: closeRef.current, pinkBtn: pinkRef.current, }; }); if (!open) return null; return ( <div> <br /> <button ref={closeRef} onClick={onClose}> × </button> <h1>Color Change</h1> <div> <div ref={pinkRef}>color1</div> </div> </div> ); } export default React.forwardRef(CustomModal);
ย
์ ์ฝ๋๋ useImperativeHandle Hook์ ํฌํจํ
CustomModal
์ปดํฌ๋ํธ์ ์ ์ฒด ์ฝ๋์
๋๋ค. ref๋ฅผ ์ ๋ฌ๋ฐ๋ ์์ ์ปดํฌ๋ํธ์ธ CustomModal
์์ย forwardRef() ํจ์๋ก ๊ฐ์ผ ํ exportํด์ผ useImperativeHandle Hook์ ์ธ์๋ก ref๋ฅผ ์ ๋ฌ๋ฐ์ ์ ์๊ธฐ ๋๋ฌธ์ ๋ง์ง๋ง ์ฝ๋์ export default React.forwardRef(CustomModal)๋ฅผ ๋ฃ์ด์ค๋๋ค. ย
<button onClick={() => { modalRef.current.pinkBtn.style = "width:50px; height:50px; background:pink;"; }} > Pink Btn </button>;
ย
๋ง์ง๋ง์ผ๋ก App.js๋ก ๋์์ Pink Btn ๋ฒํผ onClick ์ด๋ฒคํธ ํธ๋ค๋ฌ์ modalRef.current.pinkBtn.style์ ๋ฃ์ด css ์คํ์ผ์ ๋ณ๊ฒฝํด์ค๋๋ค. width:50px; height:50px; background:pink;์ ๊ฐ์ ์ค์ ํด ๋๋น, ๋์ด์ ๋ฐฐ๊ฒฝ์์ ๋ณ๊ฒฝํด์ฃผ์์ต๋๋ค. ์๋ ๊ทธ๋ฆผ 9-5๋ Pink Btn์ ํด๋ฆญํ์ฌ โcolor1โ ํ
์คํธ์ ์คํ์ผ์ ๋ฐ๊พผ ๊ฒฐ๊ณผ์
๋๋ค.
ย
ย
์์ ๋์ผํ ๋ฐฉ์์ผ๋ก ๋ชจ๋ฌ์ ๋ซ๊ธฐ ๋ฒํผ, Skyblue Btn๊ณผ Tomato Btn์ ๋ง๋ค์ด ์๋ ๋ง๋ค๊ณ ์ ํ๋ ๊ทธ๋ฆผ 9-1๊ณผ ๊ฐ์ ์ ํ๋ฆฌ์ผ์ด์
์ ์์ฑํฉ๋๋ค. ์๋๋ ์ต์ข
์ฝ๋์
๋๋ค.
ย
import { useState, useRef } from "react"; import CustomModal from "./CustomModal"; function App() { const [open, setOpen] = useState(false); const modalRef = useRef(); return ( <> <button onClick={() => setOpen(true)}>Open</button> <button onClick={() => { modalRef.current.pinkBtn.style = "width:50px; height:50px; background:pink;"; }} > Pink Btn </button> <button onClick={() => { modalRef.current.skyblueRefBtn.style = "width:50px; height:50px; background:skyblue;"; }} > Skyblue Btn </button> <button onClick={() => { modalRef.current.tomatoBtn.style = "width:50px; height:50px; background:tomato;"; }} > Tomato Btn </button> <CustomModal ref={modalRef} open={open} onClose={() => setOpen(false)} /> </> ); } export default App;
ย
import React from "react"; import { useRef, useImperativeHandle } from "react"; function CustomModal({ open, onClose }, ref) { const closeRef = useRef(); const pinkRef = useRef(); const skyblueRef = useRef(); const tomatoRef = useRef(); useImperativeHandle(ref, () => { return { closeBtn: closeRef.current, pinkBtn: pinkRef.current, skyblueRefBtn: skyblueRef.current, tomatoBtn: tomatoRef.current, }; }); if (!open) return null; return ( <div> <br /> <button ref={closeRef} onClick={onClose}> × </button> <h1>Color Change</h1> <div> <div ref={pinkRef}>color1</div> <div ref={skyblueRef}>color2</div> <div ref={tomatoRef}>color3</div> </div> </div> ); } export default React.forwardRef(CustomModal);
ย
ย