useRef Hook

박종한·2020년 3월 31일
0

1번째 기능

useRef 훅은 DOM객체를 이용할 수 있다.
따라서, focus()같은 기능이 가능한데,

import React, { useState } from 'react';

function InputSample() {
    const [string, setString] = useState({
        height: '',
        weight: '',
    });
    const { height, weight } = string;
    const onChange = event => {
        const { name, value } = event.target;
        setString({
            ...string,
            [name]: value
        });
    }
    const onInit = () => {
        setString({
            height: '',
            weight: '',
        });
    }
    return (
        <>
            <div>
                <label htmlFor="height">:</label>
                <input type="input" onChange={onChange} value={height} name="height" />
            </div>
            <div>
                <label htmlFor="weight">몸무게:</label>
                <input type="input" onChange={onChange} value={weight} name="weight" />
            </div>
            <button onClick={onInit}>init</button>
            <div>
                <b>height: </b>
                {height}
            </div>
            <div>
                <b>weight: </b>
                {weight}
            </div>
        </>
    )
}

export default InputSample;

저번에 올렸던 게시물인 useState() 설명글의 코드를 그대로 가져와봤다.
그런데, 여기서 init버튼을 누르면 초기화가 되는데, 문제는 input창에서 커서가 벗어난다는 점이다.

만약 초기화를 누르면 height 쪽에 커서가 뜨도록 하고 싶다면 DOM에 접근해서 focus()를 사용해야 한다.

그럴때 사용하는게 useRef()인데, 사용법은 다음과 같다.
1. 변수를 만들고 값을 useRef()로 해준다.
2. input 태그안에 ref라는 키워드와 함께 아까 만든 변수를 값으로 넣어준다.
3. 초기화버튼 클릭시 변수.current.focus()를 입력한다.

1 >> const heightInput = useRef();
2 >> <input ~~~~~ ref={heightInput}/>
3 >> 
    const onInit = () => {
        setString({
            height: '',
            weight: '',
        });
        heightInput.current.focus();
    }

이렇게하면 초기화버튼을 누를시, heightInput이 가리키는 DOM 즉, input 태그로 커서가 이동한다. (마우스 커서가 아니라, 키보드 버퍼 커서)

2번째 기능

바뀌어도 리렌더링이 필요하지 않지만, 유지되어야 하는 숫자(즉, 화면에 출력되진 않지만 리렌더링이 되도 계속 값이 유지되어야 할 때)에 useRef()를 사용할 수도 있다.
주로 비동기함수에 쓰이는 id나 외부라이브러리 사용시 생성된 인스턴스, scroll 위치 등인데, 값이 바뀌어도 컴포넌트가 리렌더링 되지 않는다.

게시물을 추가할 때 게시물마다 붙는 고유 id가 1씩 늘어날 때 기존의 유지할 때 사용한다.

const nextId = useRef(4);

이런식으로 하면 현재는 4지만, 글을 올려 5가 되면, 리렌더링이 되어도 값이 유지가 된다.
하지만 이 값 자체가 리렌더링에 관여하지 않는다. 대체적으로 서버로부터 뭐 글의 개수 count 같은 걸 받아올 때, 매번 글을 올리다보면 서버에 저장된 글의 개수가 바뀌기 때문에 그런걸 useRef를 통해서 관리하는 모양인데, 이 역시 값을 조작하기 위해서는 nextId.current 키워드를 사용함. 즉, useRef()에서 괄호안에 들어갈 수 있는 것은 DOM객체 뿐만이 아니라, 숫자나 문자열 같은 리렌더링 시에도 기억할 필요가 있는 숫자들이 들어가는 것 같다.

예, 사람들의 신장과 체중을 기록하는 사이트

  const users = [
    {
      id: 1,
      height: 185,
      weight: 75,
    },
    {
      id: 2,
      height: 167,
      weight: 50,
    },
    {
      id: 3,
      height: 173,
      weight: 80,
    }
  ]

  const nextId = useRef(4);

  const onCreate = () => {
    console.log(nextId.current);
    nextId.current += 1; // 생성이 되면 nextId 1증가
  }
profile
코딩의 고수가 되고 싶은 종한이

0개의 댓글