useRef

로선생·2021년 8월 31일

Hooks

목록 보기
6/6

useRef는 함수형 컴포넌트에서 ref를 쉽게 사용할 수 있도록 해준다.

Average 컴포넌트에서 등록 버튼을 눌렀을 때 포커스가인풋 쪽으로 넘어가도록 코드를 작성해 보자.

import React, { useState, useMemo, useCallback, useRef } from "react";

const getAverage = (numbers) => {
  console.log("평균값 계산 중");
  if (numbers.length === 0) return 0;
  const sum = numbers.reduce((a, b) => a + b);
  return sum / numbers.length;
};

const Average = () => {
  const [list, setlist] = useState([]);
  const [number, setNumber] = useState("");
  const inputEl = useRef(null);

  const onChange = useCallback((e) => {
    setNumber(e.target.value);
  }, []); // 컴포넌트가 처음 렌더링 될 때만 함수 생성
  const onInsert = useCallback(() => {
    const nextList = list.concat(parseInt(number));
    setlist(nextList);
    setNumber("");
    inputEl.current.focus();
  }, [number, list]); // number 혹은 list가 바뀌었을 때만 함수 생성

  const avg = useMemo(() => getAverage(list), [list]);

  return (
    <div>
      <input value={number} onChange={onChange} ref={inputEl} />
      <button onClick={onInsert}>등록</button>
      <ul>
        {list.map((value, index) => (
          <li key={index}>{value}</li>
        ))}
      </ul>
      <div>
        <b>평균값:</b> {avg}
      </div>
    </div>
  );
};

export default Average;

useRef를 사용하여 ref를 설정하면 useRef를 통해 만든 객체 안의 current값이 실제 엘리먼트를 가리킨다.

로컬 변수 사용하기

컴포넌트 로컬 변수를 사용해야 할 때도 useRef를 활용할 수 있다.
로컬 변수란 렌더링과 상관없이 바뀔 수 있는 값을 의미한다.
클래스 형태로 작성된 컴포넌트가 로컬 변수를 사용해야 할 때는 다음과 같다.

import React, { Component } from "react";

class MyComponent extends Component {
  id = 1;
  setId = (n) => {
    this.id = n;
  };
  printId = () => {
    console.log(this.id);
  };
  render() {
    return <div>My Component</div>;
  }
}

이렇게 값이 바뀌어도 렌더링되지 않는 값을 의미한다.
함수형으로 작성하면 다음과 같다.

import React, { useRef } from "react";

const RefSample = () => {
  const id = useRef(1);
  const setId = (n) => {
    id.current = n;
  };
  const printId = () => {
    console.log(id.current);
  };
  return <div>refsample</div>;
};

export default RefSample;

이렇게 ref안의 값이 바뀌어도 컴포넌트에 렌더링되지 않는다는 점에 주의하자.

profile
이제는 이것저것 먹어요

0개의 댓글