[React Hooks] useRef

chxxrin·2024년 7월 29일
0

ReactHooks

목록 보기
3/3
const ref = useRef(value);
  • ref object를 반환해준다
  • 값은 {current:value}
  • ref object는 수정이 가능하다
  • 반환된 ref는 컴포넌트의 전 생애주기를 통해 유지가 된다
  • 컴포넌트가 계속 렌더링되어도 unmount되기 전까지는 값을 유지한다는 뜻

즉, useRef는 변화는 감지해야 하지만 렌더링될때마다 변경이 되지는 않아야 할 때 사용한다

const countRef = useRef(0);

<p>Ref : {countRef.current}</p>

useRef 변수인 countRef의 값을 가져오려면 {countRef.current}

언제 사용해?

1. 변수관리

  • state변화 → 렌더링 → 컴포넌트 내부 변수들 초기화

  • 그래서 원하지 않는 렌더링때문에 곤란해질때가 있다.

  • ref의 변화 → 렌더링X → 변수들의 값이 유지됨

  • state변화 → 렌더링 → 그래도 ref의 값은 유지됨

  const increaseCountState = () => {
    setCount(count + 1);
  };
  const increaseCountRef = () => {
    countRef.current++;
  };
  • 이 코드를 보면 state올려 버튼을 누르면 화면이 계속 렌더링되기 때문에 숫자가 올라가지만 ref올려 버튼을 누르면 화면이 렌더링되지 않기 때문에 숫자가 올라가지 않는 것처럼 보인다.
  • 근데 실제로 값이 올라가지 않는것일까?
  • 그건 아니다! 사실은 ref를 사용해도 값이 증가하는데 화면이 렌더링되지 않는 것이기 때문에 값이 올라가지 않는 것처럼 보일뿐이다.
  • 이 때, ref버튼을 누르다가 state버튼을 누르면 화면이 렌더링되면서 그제서야 개수가 증가하는 것을 볼 수 있다.

Ref의 장점은?

값이 엄청 자주 바뀌는 값을 state에 넣어놓게 되면 계속 렌더링되므로 성능에 매우 안좋아진다.

근데 이 때 ref를 사용하면 렌더링되지 않으므로 성능이 더 좋아진다!!

Ref와 변수var의 다른점은?

변수는 렌더링이 되면 계속해서 0으로 초기화가 되지만 ref는 렌더링이 되어도 초기화가 되지 않는다!

2. DOM요소에 접근

ref={ref변수명}
  • ref요소를 사용해 focus()를 줄 때
  • 손쉽게 input요소에 접근할 수 있음
  • document.querySelector() 같음
  • ref는 아무리 수정해도 렌더링은 되지 않기 때문에 화면이 업데이트 되지 않는다.
const ref = useRef(value);

<input ref={ref}/>

⇒ 이렇게 하면 바로 ref 변수에 접근할 수 있다!

새로고침 누르면 바로 로그인 창에 focus되도록 하기

그저 ref={ref변수명} 을 쓰면 된다

  const inputRef = useRef();
  useEffect(() => {
    inputRef.current.focus();
  }, []);

  const login = () => {
    alert(`환영합니다. ${inputRef.current.value}`);
    inputRef.current.focus();
  };
<input ref={inputRef} type="text" placeholder="username" />
<button onClick={login}>login</button>

전체코드

import { useState, useRef, useEffect } from "react";

import "./App.css";

function App() {
  const [count, setCount] = useState(1);
  const renderCount = useRef(1);

  useEffect(() => {
    renderCount.current++;
    console.log("렌더링수:", renderCount.current);
  });

  const countRef = useRef(0);
  let countVar = 0;
  const [renderer, setRenderer] = useState(0);
  const countRef2 = useRef(0);
  console.log(countRef);
  const increaseCountState = () => {
    setCount(count + 1);
  };
  const increaseCountRef = () => {
    countRef.current++;
    console.log("ref:", countRef.current);
  };
  const increaseRef = () => {
    countRef2.current++;
    console.log(`ref: ${countRef2.current}`);
  };

  const increaseVar = () => {
    countVar++;
    console.log(`var : ${countVar}`);
  };

  const doRender = () => {
    setRenderer(renderer + 1);
  };
  const printResults = () => {
    console.log(`ref: ${countRef.current}, var: ${countVar}`);
  };

  const inputRef = useRef();
  useEffect(() => {
    inputRef.current.focus();
  }, []);

  const login = () => {
    alert(`환영합니다. ${inputRef.current.value}`);
    inputRef.current.focus();
  };
  return (
    <>
      <p>State: {count} </p>
      <p>Ref : {countRef.current}</p>
      <button onClick={increaseCountState}>State 올려</button>
      <button onClick={increaseCountRef}>Ref 올려</button>
      <p>Ref : {countRef.current}</p>
      <p>Var : {countVar}</p>
      <button onClick={doRender}>render</button>
      <button onClick={printResults}>Ref, Var 값 출력</button>
      <button onClick={increaseRef}>Ref 올려</button>
      <button onClick={increaseVar}>Var 올려</button>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>올려</button>

      <div>
        <input ref={inputRef} type="text" placeholder="username" />
        <button onClick={login}>login</button>
      </div>
    </>
  );
}

export default App;

0개의 댓글

관련 채용 정보