const usernameChangeHandler = (event) => {
setEnteredUsername(event.target.value);
};
const ageChangeHandler = (event) => {
setEnteredAge(event.target.value);
};
setEnteredUsername()
๋ก state๋ฅผ ์
๋ฐ์ดํธํ๊ณ ์๋๋ฐ, ํ์ฌ ์์ฑ๋ ์ฝ๋๋ฅผ ๋ณด๋ฉด ํค๊ฐ์ ์
๋ ฅ ๋ฐ์ ๋ ๋ง๋ค ๊ณ์ state๋ฅผ ์
๋ฐ์ดํธํ๊ณ ์๋ค.useRef()
ํ
์ ์ฌ์ฉํ๋ฉด ์ฝ๋๋ฅผ ๋ณด๋ค ํจ์จ์ ์ผ๋ก ์์ฑํ ์ ์๋ค.
useRef()
๋ฅผ ์ฌ์ฉํ๋ฉด DOM ์์์ ์ ๊ทผํ์ฌ ์์ ํ ์ ์๊ฒ ํด์ค๋ค. HTML ์์์ ์ฐ๊ฒฐํ์ฌ ํด๋น ์์์ ์์ ํ ์ ์๋๋ก ํ๋ ๊ฐ์ ๋ฐํํ๋ค.- ์ด๊ธฐ๊ฐ์ ์ค์ ํ์ง ์์ผ๋ฉด undefined์ด๋ค.
- ๐ ์ฐธ๊ณ
๋ชจ๋ ๋ฆฌ์กํธ ํ ๊ณผ ๋ง์ฐฌ๊ฐ์ง๋ก useRef๋ ํจ์ํ ์ปดํฌ๋ํธ ์์์๋ง ์ฌ์ฉ์ด ๊ฐ๋ฅํ๋ค.
//์ฌ์ฉ์ ์ด๋ฆ ์
๋ ฅํ๋ ์ธํ๊ณผ ์ฐ๊ฒฐํ ref ์์ฑ
const nameInputRef = useRef();
//์ฌ์ฉ์ ๋์ด ์
๋ ฅํ๋ ์ธํ๊ณผ ์ฐ๊ฒฐํ ref ์์ฑ
const ageInputRef = useRef();
useRef()
๋ก ์์ฑ๋๋ ref ๊ฐ์ ํญ์ current prop์ ๊ฐ์ง๊ณ ์๋ ๊ฐ์ฒด์ด๋ค.
ref={nameInputRef}
, ref={ageInputRef}
<input
id="username"
type="text"
// โ
ref
ref={nameInputRef}
/>
//...
<input
id="age"
type="number"
// โ
ref
ref={ageInputRef}
/>
nameInputRef
์ ageInputRef
์ ์ ์ฅ๋ ๊ฐ์ ์ด ์ธํ์ ๊ธฐ๋ฐ์ผ๋ก ๋ ๋๋ง๋ ๋ค์ดํฐ๋ธ DOM ์์์ ์ค์ ํ๋ค.nameInputRef
์ ageInputRef
์์ ๋ ๊ฐ์ ๋์ค์ Real DOM์ ์์๊ฐ ๋๋ค.const addUserHandler = (event) => {
event.preventDefault();
//โ
3. ์์๋ฅผ ๋ง๋ค๊ณ ref์ ์ ์ฅ๋ ํ์ฌ input ๊ฐ ์ ์ฅ
// ์กฐ๊ฑด ๊ฐ์ ์ฌ์ฉํ ์์๋ฅผ state๋์ ref๋ก ๊ฐ์ ธ์จ ์์๋ก ๋ค ๋ฐ๊พผ๋ค.
const enteredRefName = nameInputRef.current.value;
const enteredRefAge = ageInputRef.current.value;
if (
enteredRefName.trim().length === 0 ||
enteredRefAge.trim().length === 0
) {
setError({
title: "Invalid input",
message: "Please enter a valid name and age (non-empty values).",
});
return;
}
if (+enteredRefAge < 1) {
setError({
title: "Invalid age",
message: "Please enter a valid age (> 0).",
});
return;
}
props.onAddUser(enteredRefName, enteredRefAge);
//...
};
// โ setState ์ญ์
// setEnteredUsername("");
// setEnteredAge("");
//โ
nameInputRef.current.value = "";
ageInputRef.current.value = "";
(Uncontrolled Component)
๊ฐ ๋๋ค. ์ด๋ฐ์์ผ๋ก ์ฐ๊ณ ์ถ์ง ์์ผ๋ฉด ์๋ ์์ฑํ๋ ๋๋ก state ๊ธฐ๋ฐ์ผ๋ก ์ฝ๋๋ฅผ ์์ฑํ๋ฉด ๋๋ค.import React, { useState, useRef } from "react";
import Card from "../UI/Card";
import Button from "../UI/Button";
import ErrorModal from "../UI/ErrorModal";
import classes from "./AddUser.module.css";
const AddUser = (props) => {
//โ
1. useRef() ํ
์ ์ฌ์ฉํ์ฌ ref ์์ฑ
// ์ฌ์ฉ์ ์ด๋ฆ ์
๋ ฅํ๋ ์ธํ๊ณผ ์ฐ๊ฒฐํ ref ์์ฑ
const nameInputRef = useRef();
// ์ฌ์ฉ์ ๋์ด ์
๋ ฅํ๋ ์ธํ๊ณผ ์ฐ๊ฒฐํ ref ์์ฑ
const ageInputRef = useRef();
//โ ์ด์ state ๋ ์ด์ ์ฌ์ฉํ์ง ์์๋ ๋๊ธฐ ๋๋ฌธ์ ์ญ์
// const [enteredUsername, setEnteredUsername] = useState("");
// const [enteredAge, setEnteredAge] = useState("");
const [error, setError] = useState();
const addUserHandler = (event) => {
event.preventDefault();
//โ
3. ์์๋ฅผ ๋ง๋ค๊ณ ref์ ์ ์ฅ๋ ํ์ฌ input ๊ฐ ์ ์ฅ
// ์กฐ๊ฑด ๊ฐ์ ์ฌ์ฉํ ์์๋ฅผ state๋์ ref๋ก ๊ฐ์ ธ์จ ์์๋ก ๋ค ๋ฐ๊พผ๋ค.
const enteredRefName = nameInputRef.current.value;
const enteredRefAge = ageInputRef.current.value;
if (
enteredRefName.trim().length === 0 ||
enteredRefAge.trim().length === 0
) {
setError({
title: "Invalid input",
message: "Please enter a valid name and age (non-empty values).",
});
return;
}
if (+enteredRefAge < 1) {
setError({
title: "Invalid age",
message: "Please enter a valid age (> 0).",
});
return;
}
props.onAddUser(enteredRefName, enteredRefAge);
// โ setState ์ญ์
// setEnteredUsername("");
// setEnteredAge("");
//โ
4. ์ผ๋ฐ์ ์ผ๋ก DOM์ ์ง์ ์กฐ์ํ๋ฉด ์๋๊ธด ํ๋ฐ ์ฌ์ฉ์๊ฐ ์
๋ ฅํ ๊ฐ ์ฌ์ค์ ํ๊ธฐ ์ํ ๊ฒฝ์ฐ๋ ์ฌ์ฉํด๋ ๋ฌด๋ฐฉํ์ง๋ง ํํ ์ฐ์ด๋ ๋ฐฉ๋ฒ์ ์๋๋ค. DOM ์กฐ์ํ๊ธฐ ์ํด ref ์ฐ๋ ๊ฒฝ์ฐ๋ ๋งค์ฐ ๋๋ฌผ๊ธฐ ๋๋ฌธ! ๊ทผ๋ฐ ์ฌ๊ธฐ์ ์ธ๊ฑฐ์!
nameInputRef.current.value = "";
ageInputRef.current.value = "";
//์ด๋ ๊ฒ ์์ฐ๊ณ ์ถ์ผ๋ฉด state ๊ธฐ๋ฐ ํด๊ฒฐ๋ฒ ์ฌ์ฉํ๋ฉด ๋๋ค.
};
// โ state ๊ด๋ จ๋ ๋ถ๋ถ ๋ค ์ญ์
// const usernameChangeHandler = (event) => {
// setEnteredUsername(event.target.value);
//โ๏ธ ref๋ฅผ ์ฝ์์ ์ฐ์ด๋ณด๋ฉด current ๊ฐ์ด id๊ฐ username์ธ input์ด ์ถ๋ ฅ๋๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
//console.log(nameInputRef);
//console.log(nameInputRef.current.value);
// };
// const ageChangeHandler = (event) => {
// setEnteredAge(event.target.value);
// console.log(ageInputRef);
// };
const errorHandler = () => {
setError(null);
};
//โ
2. ์ฐ๊ฒฐํ JSX ์ฝ๋์ ref prop ์ถ๊ฐํ์ฌ ref ์ฐ๊ฒฐํ๊ธฐ
//ref={nameInputRef}, ref={ageInputRef}
return (
<>
{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}
// โ
ref
ref={nameInputRef}
/>
<label htmlFor="age">Age (Years)</label>
<input
id="age"
type="number"
// โ value={enteredAge}
// โ onChange={ageChangeHandler}
// โ
ref
ref={ageInputRef}
/>
<Button type="submit">Add User</Button>
</form>
</Card>
</>
);
};
export default AddUser;
state๋ฅผ ํค ๋ก๊ทธ ๊ธฐ๋ก์ฉ์ผ๋ก ์ฌ์ฉํ๋๊ฑด ๋ณ๋ก ์ข์ง ์๊ธฐ ๋๋ฌธ์ ๊ฐ๋ง ์ฝ๊ณ ์ถ์ง ์๋ฌด ๊ฒ๋ ๋ฐ๊ฟ ๊ณํ์ด ์๋ค๋ฉด ref๊ฐ ๋ซ๋ค.
ref
์ ์ ์ฝ๋๋ก ๊ตฌํ ๊ฐ๋ฅ
ํ์ง๋ง DOM ์กฐ์ํ๋ค๋ ์๋นํ ์์ธ์ ์ธ ์ผ์ ํด์ผ ํจ
ref ์ฌ์ฉํ ์ปดํฌ๋ํธ๋ (๋ฆฌ์กํธ์ ์ํด)์ ์ด๋์ง ์๋ ์ปดํฌ๋ํธ
state
ํ์คํ ๋ ๊น๋ํจ
ํ์ง๋ง ์ฝ๋๋ฅผ ref๋ณด๋ค ๋ ๋ง์ด ์จ์ผ ํจ
state ์ฌ์ฉํ ์ปดํฌ๋ํธ๋ (๋ฆฌ์กํธ์ ์ํด)์ ์ด๋๋ ์ปดํฌ๋ํธ