나의 주니어 개발 일기/REACT
[REACT] useRef로 컴포넌트 변수 생성하기
추억을 백앤드하자
2025. 6. 27. 15:02
728x90
반응형
SMALL
useRef로 컴포넌트 변수 생성하기
useState
- State를 생성
- 컴포넌트 내부의 변수로 활용 가능
- 값이 변경되면 컴포넌트 리렌더링
useRef
- Reference 객체를 생성
- 컴포넌트 내부의 변수로 활용 가능
어떤 경우에도 리렌더링을 유발하지 않음
컴포넌트 내부에서 랜더링에 영향을 미치치 않아야 되는 변수를 생성할 때 활용할 수 있다.
아래와 같이 사용하면 전체 Register 컴포넌트에 영향을 안주면서 오직 refObj만 렌더링 된다.
결과는 Register 랜더링은 최초 한번만 되고, 오로지 refObj값만 변경된다.
const Register = () => {
const [input, setInput] = useState({
name : "",
birth : "",
country : "",
bio : ""
});
const refObj = useRef(0);
console.log("Register 랜더링");
const onChange = () => {
setInput({
...input,
[e.target.name]: e.target.value,
})
}
return(
<div>
<button onClick={() => {
refObj.current++;
console.log(refObj.current);
}} />
<div>
<input
name="name"
value={input.name}
onChange={onChange}
placeholder={"이름"}
/>
</div>
...
...
useRef를 사용해서 focus 해보기
const Register = () => {
const [input, setInput] = useState({
name : "",
birth : "",
country : "",
bio : ""
});
const inputRef = useRef(0);
const onSubmit= () => {
if(input.name === ""){
//이름을 입력하는 DOM 요소에 포커스
console.log(inputRef.current);
inputRef.current.focus();
}
};
return(
<div>
<div>
<input
ref={inputRef}
name="name"
value={input.name}
onChange={onChange}
placeholder={"이름"}
/>
</div>
...
<button onClick={onSubmit}>제출</button>
</div>
);
}

이름 값이 없을때 focus가 된다.
간단한 회원가입 폼 만들기
Register.jsx
import { useState, useRef } from "react";
//간단한 회원가입 폼
//1. 이름
//2. 생년월일
//3. 국적
//4. 자기소개
const Register = () => {
const [input, setInput] = useState({
name : "",
birth : "",
country : "",
bio : ""
});
const refObj = useRef(0);
const inputRef = useRef(0);
const onChange = (e) => {
refObj.current++;
console.log(refObj.current);
setInput({
...input,
[e.target.name]: e.target.value,
})
}
const onSubmit= () => {
if(input.name === ""){
//이름을 입력하는 DOM 요소에 포커스
console.log(inputRef.current);
inputRef.current.focus();
}
};
return(
<div>
<div>
<input
ref={inputRef}
name="name"
value={input.name}
onChange={onChange}
placeholder={"이름"}
/>
</div>
<div>
<input
name="birth"
value={input.birth}
onChange={onChange}
type="date"/>
</div>
<div>
<select
name="country"
value={input.country}
onChange={onChange}>
<option ></option>
<option value="kr">한국</option>
<option>미국</option>
<option>일본</option>
</select>
</div>
<div>
<textarea
name="bio"
value={input.bio}
onChange={onChange}/>
</div>
<button onClick={onSubmit}>제출</button>
</div>
);
}
export default Register;
App.jsx
import "./App.css";
import { useState } from "react";
import Register from './components/Register';
function App() {
return (
<>
<Register />
</>
);
}
export default App;
궁금증
굳이 useRef, useState를 사용하지 않고 변수 값을 컴포넌트 외부에서 선언할 수도 있다.
그러나 치명적인 문제가 존재한다.
변수값 count를 컴포넌트 외부로 빼고 변경을 시킨다.
Register.jsx
let count = 0;
//간단한 회원가입 폼
//1. 이름
//2. 생년월일
//3. 국적
//4. 자기소개
const Register = () => {
const [input, setInput] = useState({
name : "",
birth : "",
country : "",
bio : ""
});
const refObj = useRef(0);
const inputRef = useRef(0);
const onChange = (e) => {
count++;
console.log("컴포넌트 밖에 변수", count);
refObj.current++;
console.log(refObj.current);
...
...
App.jsx
import "./App.css";
import { useState } from "react";
import Register from './components/Register';
function App() {
return (
<>
<Register />
<Register />
</>
);
}
export default App;

그리고 Register 컴포넌트를 2번호출 했을때 문제가 발생한다.
Register 가 2번 호출되었지만 내부의 상태값들은 각각 관리되어야 하지만 컴포넌트 외부에 선언된 변수는 공유가 된다.
이러한 문제 때문에 변화될 수 있는 값은 왠만해서는 useState 또는 useRef를 사용하는것이 보다 안정적이고 권장되는 방식이다.
728x90
반응형
LIST