[React] useRef์ ์ฌ์ฉ ์์
๋ฆฌ์กํธ ํ ์ค์ useRef ํ ์ DOM์ ์ ๊ทผํ ์ ์๋๋ก ํด์ฃผ๊ฑฐ๋, ๊ฐ์ ์ ์ฅํด์ ์ฌ์ฉํ ์ ์๋ ํ ์ด๋ค.
(์ด๋ ์ ์ฅํ ๊ฐ์ ์ปดํฌ๋ํธ์ ๋ ๋๋ง๊ณผ ๋ฌด๊ดํ๊ฒ ์ ์ง๋๋ค!)
์์ง๊น์ง useRef๋ฅผ input ํ๊ทธ๋ฅผ ํฌ์ปค์ฑํ ๋ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ๊ฐ ๋๋ถ๋ถ์ด์๋๋ฐ, ๋ค๋ฅธ ์์๊ฐ ๋ ์๋์ง ์ถ๊ฐ์ ์ผ๋ก ์ ๋ฆฌํด๋ณด๋ ค๊ณ ํ๋ค.
ํฌ์ปค์ฑ ํ๊ธฐ
๋ฒํผ์ ํด๋ฆญํ๊ฑฐ๋, ์ด๋ฒคํธ ํธ๋ค๋ฌ์ input ์์ ๋ฑ์ ํฌ์ปค์ฑ์ ํ ์ ์๋ค.
{isLoggedIn && (
<Icons>
{showSearchInput && (
<SearchInput
inputRef={searchInputRef}
setShowSearchInput={setShowSearchInput}
/>
)}
<SearchIcon onClick={() => setShowSearchInput(true)} />
...
</Icons>
)}
ํ๋ก์ ํธ์์๋ ์ธ๋ถ์์ญ์ ํด๋ฆญํ์ ๋๋ฅผ ํ๋จ์์ ๊ฒ์์ฐฝ์ด ๋ซํ๋๋ก ์ฌ์ฉํ ์ ๋ ์๋ค.
// ๊ฒ์์ฐฝ ์ธ๋ถ ํด๋ฆญ ์ฌ๋ถ ํ๋จ
const clickOutside = (e: any) => {
if (
searchInputRef.current &&
!searchInputRef.current.contains(e.target as Node)
) {
setShowSearchInput(false);
}
};
๊ฐ ์ ์ฅํ๊ธฐ
useRef์ ๊ฐ์ ์ ์ฅํด์ ์ด์ ๊ฐ, ํ์ฌ ๊ฐ์ ๋น๊ตํ ๋ ์ฌ์ฉํ ์ ์๋ค..current
๋ผ๋ ํ๋กํผํฐ๋ก ๊ฐ์ ์ ๊ทผํ๊ฑฐ๋ ๋ณ๊ฒฝํ ์ ์๋ค.
...
const [count, setCount] = useState(0);
const prevCountRef = useRef();
useEffect(() => {
prevCountRef.current = count;
});
const prevCount = prevCountRef.current;
return (
<>
<h1>Now: {count}, before: {prevCount}</h1>
<button onClick={() => setCount(count + 1)}>์นด์ดํธ ์ฆ๊ฐ</button>
</>
);
์ธ๋ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์ํธ์์ฉํ๊ธฐ
useRef์ ์ธ๋ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์ธ์คํด์ค๋ฅผ ์ ์ฅํด์ ์ฌ์ฉํ ์ ์๋ค..!
useRefdใ ์ ์ฅ๋ ๊ฐ์ ๋ฆฌ๋ ๋๋ง์ ์ํฅ์ ๋ฐ์ง ์๊ธฐ ๋๋ฌธ์ ํ๋์ ์ธ์คํด์ค๋ฅผ ๊ณ์ ์ฌ์ฉํ ์ ์๋ค๋ ์ ์์ ํจ์จ์ ์ผ ๊ฒ ๊ฐ๋ค๋ ์๊ฐ.
const mapContainerRef = useRef(null);
const mapRef = useRef(null);
useEffect(() => {
mapboxgl.accessToken = 'YOUR_MAPBOX_ACCESS_TOKEN';
const map = new mapboxgl.Map({
container: mapContainerRef.current,
style: 'mapbox://styles/mapbox/streets-v11',
center: [0, 0],
zoom: 2,
});
mapRef.current = map;
return () => map.remove();
}, []);
return <div ref={mapContainerRef} style={{ height: '400px' }} />;