๐Ÿ–ฅFrontEnd/React

useRef๋ž€, useRef ์‚ฌ์šฉ๋ฐฉ๋ฒ•, useRef ์‚ฌ์šฉ ์˜ˆ์‹œ

hellohailie 2022. 7. 27. 23:37

 

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;

 

 

๐Ÿ˜ƒ ์ž˜๋ชป๋œ ๊ฐœ๋… ์ „๋‹ฌ์ด ์žˆ๋‹ค๋ฉด ๋Œ“๊ธ€ ๋ถ€ํƒ๋“œ๋ฆฝ๋‹ˆ๋‹ค. ์ €์˜ ์„ฑ์žฅ์— ํฐ ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค๐Ÿค“