개발의 시작과 끝

2021.03.10 / React - Hooks useRef 본문

리액트

2021.03.10 / React - Hooks useRef

개발지혜 2021. 3. 10. 17:38

useRef

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

리액트를 개발하다 보면 DOM에 직접적인 접근을 해야 할 때가 있는데 이때 ref를 사용한다.

  1. input / textarea 등에 포커스를 해야 할때
  2. 특정 DOM 의 크기를 가져와야 할 때
  3. 특정 DOM 에서 스크롤 위치를 가져오거나 설정을 해야 할 때
  4. 외부 라이브러리 (플레이어, 차트, 캐로절 등) 을 사용 할 때

또한, 컴포넌트 안에서 조회 및 수정 할 수 있는 변수를 관리할 수도 있다.

 

Average 컴포넌트에서 등록 버튼을 눌렀을 때 포커스가 input 안쪽으로 넘어가는 코드

 

Average.js

import React, { useState, useMemo, 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(
    e => {
      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>
        MyComponent
      </div>
    );
  }
}

export default MyComponent;

클래스 형태의 컴포넌트로 따지자면 위와 같은 코드이다.

이러한 코드를 만약 함수형 컴포넌트로 작성하면 다음과 같이 작성할 수 있다.

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 안의 값은 바뀌어도 컴포넌트가 렌더링 되지 않는다는 점이다.

렌더링과 관련되지 않은 값을 관리할 때만 이렇게 작성해야 한다.

 

 

참고

- velopert.com/1148

- velog.io/@velopert/react-hooks

'리액트' 카테고리의 다른 글

2021.03.14 / Redux  (0) 2021.03.14
2021.03.10 / React - Hooks useCallback  (0) 2021.03.10
2021.03.10 / React - Hooks useMemo  (0) 2021.03.10
2021.03.08 / React - Hooks useReducer  (0) 2021.03.08
2021.03.07 / React - Hooks useContext  (0) 2021.03.07