useRef๋?
1. ํน์ ์์์ DOM ์ฃผ์๊ฐ์ ๊ฐ์ ธ์ค๋ React Hook์ด๋ค.
React๋ ๊ธฐ๋ณธ์ ์ผ๋ก DOM์ ์ง์ ์ ๊ทผํ๋ ๊ฒ์ ๊ธ์งํ๊ณ ์๋ค.
React๋ ๊ฐ์ DOM์ ์ฌ์ฉํด์ SPA๋ฅผ ๊ตฌํํ๊ธฐ ๋๋ฌธ์, DOM์ ์ง์ ์กฐ์ํ๋ ๊ฒ์ React์ ์๋ ๋ฐฉ์๊ณผ๋ ๋ง์ง ์๊ณ , ์ํ๋ ๊ฒฐ๊ณผ๊ฐ ๋์ค์ง ์์ ์๋ ์๊ธฐ ๋๋ฌธ์ด๋ค.
๊ทธ๋ผ์๋ DOM์ ์ง์ ์ ๊ทผํด์ผํ๋ ์์ธ ์ํฉ๋ค์ด ์๋ค. ๋ฐ๋ก DOM ์๋ฆฌ๋จผํธ์ ์ฃผ์๊ฐ์ ํ์ฉํด์ผ ํ๋ ๊ฒฝ์ฐ๋ก, ๊ฐ์ฅ ๋ํ์ ์ธ ์์๋ ํน์ ์์์ ํฌ์ปค์ค๋ฅผ ์ค์ ํด์ผํ๋ ์ํฉ์ด ์๋ค. ์ด๋ด ๋ useRef๋ฅผ ์ฌ์ฉํด์ DOM ์ฃผ์ ๊ฐ์ ๋ฐ์์ ์ฌ์ฉํ ์ ์๋ค.
ํ์ง๋ง DOM์ ์ง์ ์ ๊ทผํ๋ ๊ฒ์ React์ ์๋ ๋ฐฉ์๊ณผ ๋ง์ง ์๊ธฐ ๋๋ฌธ์, ์ด๋ฐ ์์ธ์ ์ธ ์ํฉ์ ์ ์ธํ๊ณ ๋ useRef๋ฅผ ์ฌ์ฉํ๊ฑฐ๋ DOM์ ์ง์ ์ ๊ทผํด์๋ ์ ๋๋ค.
<DOM ์๋ฆฌ๋จผํธ์ ์ฃผ์๊ฐ์ ํ์ฉํด์ผ ํ๋ ๊ฒฝ์ฐ ์์>
- focus
- text selection
- media playback
- ์ ๋๋ฉ์ด์ ์ ์ฉ
- d3.js, greensock ๋ฑ DOM ๊ธฐ๋ฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ํ์ฉ
2. DOM์ ์กฐ์ํ๋ ์ญํ ์ด์ธ์ ์ ์ ์ ์ ๋ ฅ ๊ฐ๋ ๋ฐ์์ฌ ์ ์๋ค.
(์ฌ๊ธฐ์ ์ฐ๋ฆฌ๋ DOM์ ์ค์ ๋ก ์กฐ์ํ๋ ๊ฒ ์๋๋ค. )
์ฐ๋ฆฌ๋ ์๋ก์ด ์์๋ฅผ ์ถ๊ฐํ๊ฑฐ๋ CSS ํด๋์ค๋ฅผ ๋ณ๊ฒฝํ๋๊ฒ ์๋๊ณ , ๊ทธ์ ์ฌ์ฉ์๊ฐ ์ ๋ ฅํ ๋ด์ฉ์ ๋ฐ๊พผ ๊ฒ ๋ฟ์ด๋ค.
๊ฐ์ ๋ณ๊ฒฝํ ํ์์์ด ๊ฐ๋ง ์ฝ๊ณ ์ถ๋ค๋ฉด useRef!!
useRef๋ ์ฝ๋๋ ์กฐ๊ธ ์ ์ง๋ง, DOM์ ์กฐ์ํ๋ค๋ ์์ธ์ ์ธ ์ผ์ ํด์ผํ๋ค.
useRef ์ฌ์ฉํ๊ธฐ
1. ์๋จ์ useRef import ํ๊ธฐ
import React, { useState, useRef } from "react";
2. ๋ณ์๋ก ํ ๋นํด์ฃผ๊ธฐ
const nameInputRef = useRef(); // ์ด ref ๊ฐ์ ํญ์ ๊ฐ์ฒด์ด๊ณ , current ํ๋กญ์ ๊ฐ์ง๊ณ ์๋ค.
const ageInputRef = useRef();
3. ์ปดํฌ๋ํธ ์์์ ์ฌ์ฉํ๊ธฐ
~.current.value๋ก ์ธํ ๊ฐ์ ๋ถ๋ฌ์ฌ ์ ์๋ค.
const enteredName = nameInputRef.current.value;
const enteredUserAge = ageInputRef.current.value;
useState ์ฌ์ฉํ ์ฝ๋
import React, { useState } from 'react';
import Card from '../UI/Card';
import Button from '../UI/Button';
import ErrorModal from '../UI/ErrorModal';
import Wrapper from '../Helpers/Wrapper';
import classes from './AddUser.module.css';
const AddUser = (props) => {
const [enteredUsername, setEnteredUsername] = useState('');
const [enteredAge, setEnteredAge] = useState('');
const [error, setError] = useState();
const addUserHandler = (event) => {
event.preventDefault();
if (enteredUsername.trim().length === 0 || enteredAge.trim().length === 0) {
setError({
title: 'Invalid input',
message: 'Please enter a valid name and age (non-empty values).',
});
return;
}
if (+enteredAge < 1) {
setError({
title: 'Invalid age',
message: 'Please enter a valid age (> 0).',
});
return;
}
props.onAddUser(enteredUsername, enteredAge);
setEnteredUsername('');
setEnteredAge('');
};
const usernameChangeHandler = (event) => {
setEnteredUsername(event.target.value);
};
const ageChangeHandler = (event) => {
setEnteredAge(event.target.value);
};
const errorHandler = () => {
setError(null);
};
return (
<Wrapper>
{error && (
<ErrorModal
title={error.title}
message={error.message}
onConfirm={errorHandler}
/>
)}
<Card className={classes.input}>
<form onSubmit={addUserHandler}>
<label htmlFor="username">Username</label>
<input
id="username"
type="text"
value={enteredUsername}
onChange={usernameChangeHandler}
/>
<label htmlFor="age">Age (Years)</label>
<input
id="age"
type="number"
value={enteredAge}
onChange={ageChangeHandler}
/>
<Button type="submit">Add User</Button>
</form>
</Card>
</Wrapper>
);
};
export default AddUser;
useRef ์ฌ์ฉํ ์ฝ๋
import React, { useState, useRef } from "react";
import Card from "../UI/Card";
import Button from "../UI/Button";
import ErrorModal from "../UI/ErrorModal";
import Wrapper from "../Helpers/Wrapper";
import classes from "./AddUser.module.css";
const AddUser = (props) => {
const nameInputRef = useRef(); // ์ด ref ๊ฐ์ ํญ์ ๊ฐ์ฒด์ด๊ณ , current ํ๋กญ์ ๊ฐ์ง๊ณ ์๋ค.
const ageInputRef = useRef();
const [error, setError] = useState();
const addUserHandler = (event) => {
event.preventDefault();
const enteredName = nameInputRef.current.value;
const enteredUserAge = ageInputRef.current.value;
if (enteredName.trim().length === 0 || enteredUserAge.trim().length === 0) {
setError({
title: "Invalid input",
message: "Please enter a valid name and age (non-empty values).",
});
return;
}
if (+enteredUserAge < 1) {
setError({
title: "Invalid age",
message: "Please enter a valid age (> 0).",
});
return;
}
props.onAddUser(enteredName, enteredUserAge);
nameInputRef.current.value = "";
ageInputRef.current.value = "";
};
const errorHandler = () => {
setError(null);
};
return (
<Wrapper>
{error && (
<ErrorModal
title={error.title}
message={error.message}
onConfirm={errorHandler}
/>
)}
<Card className={classes.input}>
<form onSubmit={addUserHandler}>
<label htmlFor='username'>Username</label>
<input
id='username'
type='text'
ref={nameInputRef} //nameInputRef ์์ ๋ค์ด ์๋ ๊ฒ์ ๋์ค์ ์ค์ DOM ์์๊ฐ ๋ ๊ฑฐ๋ค.
/>
<label htmlFor='age'>Age (Years)</label>
<input
id='age'
type='number'
ref={ageInputRef} //ageInputRef ์์ ๋ค์ด ์๋ ๊ฒ์ ๋์ค์ ์ค์ DOM ์์๊ฐ ๋ ๊ฑฐ๋ค.
/>
<Button type='submit'>Add User</Button>
</form>
</Card>
</Wrapper>
);
};
export default AddUser;