useRef

gyomni·2022년 2월 24일
1

React

목록 보기
2/9
post-thumbnail

useRef 로 특정 DOM 선택

  • htmljs를 사용할 때는 특정DOM선택해야 하는 상황에 document.getElementbyId() querySelector() 같은 DOM selector을 사용해서 선택함.

  • react를 사용하는 프로젝트에서도 가끔씩 DOM을 직접 선택해야 하는 상황 발생할 수 있다.
    ex)
    -> 특정 엘리먼트 크기나 위치 가져올 때,
    -> 스크롤 바 위치를 가져오거나 설정해야 할 때,
    -> focus를 설정해줘야 할 때
    -> 특정 라이브러리 사용할 때 등등

  • 특정 DOM 선택할 때 리엑트에서 ref를 사용한다.
    -> 함수형 컴포넌트에서는 useRef 라는 hook 함수 사용.
    -> 클래스형 컴포넌트에서는 React.createRef() or 콜백 함수 사용.

useRef 불러오기

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

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

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

    const onChange =(e)=>{ 
        const {name, value} =e.target; // e.target에서 name, value 추출 (필수는 아님. e.target두번쓰기 싫어서), 
        
        setInputs({
            // 새로운 객체 설정
            ...inputs,
            [name]: value, // 여기서 name값은 name이 될 수도 있고, nickname이 될 수도 있음.
        });   

    } ;

    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;

코드 파헤치기

📍

 const nameInput = useRef();
 const {name, nickname} = inputs; // 비구조화 할당을 통해 name, nickname 추출
  • useRef 호출해서 nameInput이라는 객체 생성.

📍

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>
    )
  • useRef()로 만든 객체( nameInput )를 ref라는 값으로 원하는 DOM에다가 설정.
  • 선택하고 싶은 DOM에다가 객체를 넣어줌.
    ( ref={nameInput} 설정. )

📍
DOM에 접근하기

const onReset =()=>{ 
        setInputs({
            name: '',
            nickname:'',   
        });
        nameInput.current.focus();
    };
  • 해당 DOM을 선택하고 싶을 때 : 우리가 만든ref객체(nameInput).current.원하는 작업
    -> nameInput.current.focus();
  • currentDOM을 가리키게 됨.
  • DOM APIfocus라는 함수 사용.
    -> 초기화 눌러 보면 이름에 포커스가 잡힘.
    -> 초기화 버튼 누르면 focus가 초기화 버튼에 있지 않고 이름으로 가게 됨!

useRef 로 컴포넌트 안의 변수 만들기

  • 컴포넌트 내부에서 let 키워드로 어떤 변수 선언한다면, 다음 리렌더링 될 때는 그 변수 값이 초기화가 된다.

  • 만약 계속 값을 유지하고 싶은 값을 관리하려면 uesState를 사용해야 한다.

  • uesState 같은 경우는 상태를 바꾸게 되면 컴포넌트가 리렌더링 된다.

  • 하지만 값을 바꿨을 때 굳이 리렌더링이 필요 없는 값을 관리할 때도 있다.
    -> 이때 useRef를 사용하면 됨!

useRef는 이전에 특정 DOM을 선택해야 해서ref를 사용해야 할 때 useRef라는 hook을 사용하고, 그 외에도 컴포넌트가 리렌더링 될 때 마다 계속 기억할 수 있는 어떠한 값을 관리할 때 사용한다.

  • setTimeout, setInterval 을 통해서 만들어진 id
  • 외부 라이브러리를 사용하여 생성된 인스턴스
  • scroll 위치 알고 있어야 할 때...

useRef 로 관리하는 변수는 값이 바뀐다고 해서 컴포넌트가 리렌더링되지 않는다.
리액트 컴포넌트에서의 상태는 상태를 바꾸는 함수를 호출하고 나서 그 다음 렌더링 이후로 업데이트 된 상태를 조회 할 수 있는 반면, useRef 로 관리하고 있는 변수는 설정 후 바로 조회 할 수 있다.


import React,{useRef} from 'react'; 
import UserList from './UserList';


function App(){
  const users =[
    {
        id:1,
        username: 'gyomni',
        email: 'hi1@gmail.com'
    },
    {
        id:2,
        username: 'joy',
        email: 'hi2@gmail.com'
    },
    {
        id:3,
        username: 'zoe',
        email: 'hi3@gmail.com'
    }
    ];

const nextId = useRef(4); 
  
const onCreate=()=>{
  console.log(nextId.current); // 4
  nextId.current+=1; // 여기서 리렌더링 되도 컴포넌트 값이 바뀌진 않음.
}
  return (  
  <UserList users={users}/>
  )
  }

export default App;
  • nextIduseRef로 관리해주는 이유는 (4)값이 바뀐다고 해서 컴포넌트가 리랜더링 될 필요가 없기 때문이다.
  • 컴포넌트가 리렌더링되도 값은 기억된다.
  • 즉 값이 바뀐다고 해서 컴포넌트가 리렌더링 되지 않음!

학습 : 벨로퍼트와 함께 하는 모던 리엑트

profile
Front-end developer 👩‍💻✍

0개의 댓글