๐Ÿ”ซ React_04 useRef

qhflrnfl4324ยท2022๋…„ 1์›” 9์ผ
1

React

๋ชฉ๋ก ๋ณด๊ธฐ
4/5
post-thumbnail

๐ŸŽฎ useRef๋กœ ํŠน์ • DOM ์„ ํƒํ•˜๊ธฐ

  • JavaScript์—์„œ ํŠน์ • DOM์„ ์„ ํƒํ•ด์•ผ ํ•  ๊ฒฝ์šฐ getElemnetById, querySelector์™€ ๊ฐ™์€ DOM Selector ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ DOM์„ ์„ ํƒ
  • ๋ฆฌ์•กํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ํ”„๋กœ์ ํŠธ์—์„œ๋„ DOM์„ ์ง์ ‘ ์„ ํƒํ•ด์•ผํ•˜๋Š” ์ƒํ™ฉ์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค.
    => ref ์‚ฌ์šฉ

๐ŸŽฒ ref

  • ref๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ useRef Hook ํ•จ์ˆ˜ ์‚ฌ์šฉ
  • InputSample์—์„œ ์ดˆ๊ธฐํ™” ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด ํฌ์ปค์Šค๊ฐ€ ์ดˆ๊ธฐํ™” ๋ฒ„ํŠผ์— ๋‚จ์•„์žˆ๋‹ค.
    => ์ดˆ๊ธฐํ™” ๋ฒ„ํŠผ์„ ํด๋ฆญํ–ˆ์„ ๋•Œ ์ด๋ฆ„ imput์— ํฌ์ปค์Šค๊ฐ€ ์žกํžˆ๋„๋ก ๊ตฌํ˜„

  • useRef๋ฅผ ์‚ฌ์šฉํ•ด์„œ Ref ๊ฐ์ฒด ์ƒ์„ฑ
    => ์„ ํƒํ•˜๊ณ  ์‹ถ์€ DOM์— ref ๊ฐ’์œผ๋กœ ์„ค์ •
    => onReset ํ•จ์ˆ˜์—์„œ input์— ํฌ์ปค์Šคํ•˜๋Š” focus() DOM API ํ˜ธ์ถœ
// InputSample.js
import React, { useRef, useState } from "react";

function InputSample() {
  const [inputs, setInputs] = useState({
    name: "",
    nickname: "",
  });
  const nameInput = useRef();

  const { name, nickname } = inputs;

  const onChange = (e) => {
    const { value, name } = e.target;
    setInputs({
      ...inputs,
      [name]: value,
    });
  };

  const onReset = () => {
    setInputs({
      name: "",
      nickname: "",
    });
    nameInput.current.focus();
  };

  return (
    <div>
      <input
        name="name"
        placeholder="์ด๋ฆ„"
        onChange={onChange}
        value={name}
        ref={nameInput}
      />
      <input
        name="nickname"
        placeholder="๋‹‰๋„ค์ž„"
        onChange={onChange}
        value={nickname}
      />
      <button onClick={onReset}>์ดˆ๊ธฐํ™”</button>
      <div>
        <b>๊ฐ’: </b>
        {name} ({nickname})
      </div>
    </div>
  );
}

export default InputSample;

๐ŸŽฒ ๋ฐฐ์—ด๋กœ ๋žœ๋”๋ง

  • ๋จผ์ €, ๊ทธ๋Œ€๋กœ ์ฝ”๋“œ ์ž‘์„ฑํ•ด๋ณด๊ธฐ
// UserList.js
import React from "react";

function UserList() {
  const users = [
    {
      id: 1,
      username: "velopert",
      email: "public.velopert@gmail.com",
    },
    {
      id: 2,
      username: "tester",
      email: "tester@example.com",
    },
    {
      id: 3,
      username: "liz",
      email: "liz@example.com",
    },
  ];
  return (
    <div>
      <div>
        <b>{users[0].username}</b> <span>({users[0].email})</span>
      </div>
      <div>
        <b>{users[1].username}</b> <span>({users[1].email})</span>
      </div>
      <div>
        <b>{users[2].username}</b> <span>({users[2].email})</span>
      </div>
    </div>
  );
}

export default UserList;
  • ์ปดํฌ๋„ŒํŠธ ์žฌ์‚ฌ์šฉ์„ ์œ„ํ•œ ๋ฆฌํŒฉํ† ๋ง
    => ํ•œ ํŒŒ์ผ์— ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์„ ์–ธํ•  ์ˆ˜ ์žˆ๋‹ค.
// UserList.js
import React from "react";

function User({ user }) {
  return (
    <div>
      <b>{user.username}</b> <span>({user.email})</span>
    </div>
  );
}

function UserList() {
  const users = [
    {
      id: 1,
      username: "velopert",
      email: "public.velopert@gmail.com",
    },
    {
      id: 2,
      username: "tester",
      email: "tester@example.com",
    },
    {
      id: 3,
      username: "liz",
      email: "liz@example.com",
    },
  ];

  return (
    <div>
      <User user={users[0]} />
      <User user={users[1]} />
      <User user={users[2]} />
    </div>
  );
}

export default UserList;
  • ๋™์ ์ธ ๋ฐฐ์—ด์„ ๋ Œ๋”๋งํ•ด์•ผํ•  ๋•Œ map() ์‚ฌ์šฉ
    • map() : ๋ฐฐ์—ด ์•ˆ์— ์žˆ๋Š” ๊ฐ ์›์†Œ๋ฅผ ๋ณ€ํ™˜ํ•˜์—ฌ ์ƒˆ๋กœ์šด ๋ฐฐ์—ด์„ ๋ฐ˜ํ™˜
      => ๋ฆฌ์•กํŠธ์—์„œ ๋™์ ์ธ ๋ฐฐ์—ด์„ ๋ Œ๋”๋งํ•  ๋•Œ map()์„ ์‚ฌ์šฉํ•˜์—ฌ ์ผ๋ฐ˜ ๋ฐ์ดํ„ฐ ๋ฐฐ์—ด์„ ๋ฆฌ์•กํŠธ ์—˜๋ฆฌ๋จผํŠธ๋กœ ์ด๋ฃจ์–ด์ง„ ๋ฐฐ์—ด๋กœ ๋ณ€ํ™˜
// UserList.js
import React from "react";

function User({ user }) {
  return (
    <div>
      <b>{user.username}</b> <span>({user.email})</span>
    </div>
  );
}

function UserList() {
  const users = [
    {
      id: 1,
      username: "velopert",
      email: "public.velopert@gmail.com",
    },
    {
      id: 2,
      username: "tester",
      email: "tester@example.com",
    },
    {
      id: 3,
      username: "liz",
      email: "liz@example.com",
    },
  ];

  return (
    <div>
      {users.map((user) => (
        <User user={user} />
      ))}
    </div>
  );
}

export default UserList;

  • ๋ฆฌ์•กํŠธ์—์„œ ๋ฐฐ์—ด์„ ๋ Œ๋”๋งํ•  ๋•Œ key๋ผ๋Š” props๋ฅผ ์„ค์ •ํ•˜์ง€ ์•Š์œผ๋ฉด ์—๋Ÿฌ ๋ฐœ์ƒ
    => key ๊ฐ’์€ ๊ฐ ์›์†Œ๋“ค๋งˆ๋‹ค ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๊ณ ์œ ๊ฐ’์œผ๋กœ ์„ค์ • : ์ง€๊ธˆ์€ id๊ฐ€ ๊ณ ์œ  ๊ฐ’
return (
  <div>
    {users.map((user) => (
      <User user={user} key={user.id} />
    ))}
  </div>
);
  • ๋ฐฐ์—ด ์•ˆ์˜ ์›์†Œ๊ฐ€ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๊ณ ์œ ํ•œ ๊ฐ’์ด ์—†๋Š” ๊ฒฝ์šฐ, map()์€ ์ฝœ๋ฐฑํ•จ์ˆ˜์˜ ๋‘ ๋ฒˆ์งธ ํŒŒ๋ผ๋ฏธํ„ฐ index๋ฅผ key๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
return (
  <div>
    {users.map((user, index) => (
      <User user={user} key={index} />
    ))}
  </div>
);

๐ŸŽฒ useRef๋กœ ์ปดํฌ๋„ŒํŠธ ์•ˆ์˜ ๋ณ€์ˆ˜ ๋งŒ๋“ค๊ธฐ

  • useRef Hook์€ ์ปดํฌ๋„ŒํŠธ ์•ˆ์—์„œ ์กฐํšŒ ๋ฐ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ๋Š” ๋ณ€์ˆ˜๋ฅผ ๊ด€๋ฆฌ ํ•  ์ˆ˜ ์žˆ๋‹ค.
    => useRef๋กœ ๊ด€๋ฆฌํ•˜๋Š” ๋ณ€์ˆ˜๋Š” ์„ค์ • ํ›„ ๋ฐ”๋กœ ์กฐํšŒ ๊ฐ€๋Šฅ
    (๋ฆฌ์•กํŠธ ์ปดํฌ๋„ŒํŠธ์—์„œ ์ƒํƒœ๋Š” ์ƒํƒœ๋ฅผ ๋ฐ”๊พธ๋Š” ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœ ํ›„, ๋ Œ๋”๋งํ•œ ๋‹ค์Œ ์—…๋ฐ์ดํŠธ ๋œ ์ƒํƒœ๋ฅผ ์กฐํšŒํ•  ์ˆ˜ ์žˆ๋‹ค.)

  • useRef๋กœ ๊ด€๋ฆฌํ•˜๋Š” ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฐ’์„ ๊ด€๋ฆฌ ํ•  ์ˆ˜ ์žˆ๋‹ค.

    • setTimeout, setInterval์„ ํ†ตํ•ด ์ƒ์„ฑ๋œ id
    • ์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ƒ์„ฑ๋œ ์ธ์Šคํ„ด์Šค
    • scroll ์œ„์น˜
import { useRef } from "react";

const refContariner = useRef(์ดˆ๊ธฐ๊ฐ’);

refContariner.current += 1; // ๊ฐ’ ์ˆ˜์ •
refContariner.current; // ๊ฐ’ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ
  • useRef์— ์ €์žฅ๋œ ๊ฐ’์— ์ ‘๊ทผํ•˜๊ธฐ ์œ„ํ•ด .current๋ฅผ ์‚ฌ์šฉ
    => useRef๋Š” .current ํ”„๋กœํผํ‹ฐ์— ๋ณ€๊ฒฝ ๊ฐ€๋Šฅํ•œ ๊ฐ’์„ ๋‹ด๊ณ  ์žˆ๋Š” ์ƒ์ž!

  • useRef๋Š” ์–ด๋–ค ๊ฐ€๋ณ€๊ฐ’์„ ์œ ์ง€ํ•˜๋Š”๋ฐ ์œ ์šฉ
    => useRef๋กœ ๊ด€๋ฆฌํ•˜๋Š” ๋ณ€์ˆ˜๋Š” ๊ฐ’์ด ๋ฐ”๋€Œ์–ด๋„ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ฆฌ๋ Œ๋”๋ง ๋˜์ง€ ์•Š๋Š”๋‹ค.
    (useState๋Š” ๊ฐ’์ด ๋ณ€๊ฒฝ๋  ๋•Œ๋งˆ๋‹ค ๋ฆฌ๋ Œ๋”๋ง์ด ์ผ์–ด๋‚œ๋‹ค.)

  • ์˜ˆ์ œ ์ฝ”๋“œ

// useState ๋ถ€๋ถ„ ์ฃผ์„์ฒ˜๋ฆฌ ํ•˜๋ฉด์„œ
// const, useRef, useState ๋น„๊ตํ•ด๋ณด๊ธฐ
import { useRef, useState } from "react";

export default function Example() {
  let count1 = 0;
  const count2 = useRef(0);
  const [count3, setCount3] = useState(0);

  const Check = () => {
    count1 += 1;
    console.log(`count1 : ${count1}`);
    count2.current += 1;
    console.log(`count2 : ${count2}`);
    setCount3(count3 + 1);
  };

  return (
    <>
      <h2>์˜ˆ์ œ</h2>
      <p>count1 : {count1}</p>
      <p>count2 : {count2.current}</p>
      <p>count3 : {count3}</p>
      <button onClick={Check}>check</button>
    </>
  );
}
  1. const์™€ useRef
  • check ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด ๊ฐ๊ฐ์˜ ๊ฐ’์— 1์”ฉ ์ถ”๊ฐ€ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ๋„ฃ์–ด ์ƒํƒœ ํ™•์ธ
  • check ๋ฒ„ํŠผ์„ ํด๋ฆญํ–ˆ์„ ๋•Œ ์ฝ˜์†”์ฐฝ์—์„œ const ๊ฐ’์ด ๋ณ€ํ•˜๋Š” ๊ฒƒ, useRef๋Š” object๋ฅผ ๋ฆฌํ„ดํ•˜๋Š” ๊ฒƒ์„ ํ™•์ธ
  1. const์™€ useRef ํ™•์ธ์„ ์œ„ํ•œ ๋ฆฌ๋ Œ๋”๋ง
  • ๋ฆฌ๋ Œ๋”๋ง์„ ์œ„ํ•ด ๋ฒ„ํŠผ์„ ๋ˆŒ๋Ÿฌ ๊ฐ’์„ ๋ณ€๊ฒฝํ•œ ํ›„, ์ฝ”๋“œ ์ˆ˜์ • ํ›„ ์ €์žฅ
    => ๋ฆฌ๋ Œ๋”๋ง์ด ๋˜๋ฉด์„œ const ๊ฐ’์€ 0์œผ๋กœ ์ดˆ๊ธฐํ™”, useRef๊ฐ’์€ ๋ฆฌ๋ Œ๋”๋ง ์ „ ์ €์žฅ๋˜์—ˆ๋˜ ๊ฐ’์ด ๋‚˜ํƒ€๋‚˜๊ฒŒ ๋œ๋‹ค.
  1. const, useRef ๊ทธ๋ฆฌ๊ณ  useState
  • useState๋Š” ๊ฐ’์ด ๋ณ€๊ฒฝ๋  ๋•Œ๋งˆ๋‹ค ๋ฆฌ๋ Œ๋”๋ง์ด ์ผ์–ด๋‚œ๋‹ค.
    => useState์œผ๋กœ ์ธํ•ด ๋ฆฌ๋ Œ๋”๋ง์ด ์ผ์–ด๋‚˜๋ฉด์„œ useRef ๊ฐ’๋„ ํ•จ๊ป˜ ๋ณ€๊ฒฝ๋˜์ง€๋งŒ const๊ฐ’์€ ์ดˆ๊ธฐํ™”๊ฐ€ ๋˜์–ด 1๋งŒ ์ถœ๋ ฅ๋œ๋‹ค.

์ถ”๊ฐ€์ ์œผ๋กœ ๊ณต๋ถ€ํ•  ๋ถ€๋ถ„

  • useState์˜ ๋น„๋™๊ธฐ์  ๊ฐ’ ํ• ๋‹น

์ฐธ๊ณ 

0๊ฐœ์˜ ๋Œ“๊ธ€