본문 바로가기
부트캠프 개발일지 2023-2024/React 리액트

[6주차] 리액트숙련: React Hooks - useRef

by whereanna00 2023. 11. 8.

React Hooks - useRef

DOM 요소에 접근할 수 있도록 하는 React Hook

DOM 요소에 접근한다는 말은 결국, DOM 요소를 어딘가에 저장하고 그거를 갖다쓸 수 있게 하는 것

 

useRef 는

1. 저장공간으로서 기능

2. DOM 요소 접근 방법

 

 

useRef 사용방법

useRef의 반환값은 {} 객체이다.

그 객체 안에는 key가 current, value가 우리가 넣은 '초기값'이 들어 있다.

{current: '초기값'}
import { useRef } from 'react';
import './App.css';


function App() {

  // ref: reference 참조
  const ref = useRef('초기값');
  console.log(ref);


  return (
    <div>
      App
    </div>
  );
}

export default App;

 

 

 

useRef의 value 값을 변경할 수 도 있다.

useRef도 객체니까, value 값으로 접근하는 방식 그대로 이용하여 변경값으로 값을 바꾼다.

import { useRef } from 'react';
import './App.css';


function App() {

  // ref: reference 참조
  const ref = useRef('초기값');
  console.log(ref);

  ref.current = '변경값';
  console.log("ref2", ref);

  return (
    <div>
      App
    </div>
  );
}

export default App;

 

 

 

 

 

이렇게 설정된 useRef 의 값은 컴포넌트가 계속해서 랜더링 되어도 unmount 전까지 값을 유지함

이러한 특성을 가진 덕분에 useRef는 두 가지의 용도로 사용된다

 

1. 저장공간

- state와 비슷한 역할. 단 sstate는 변화가 일어나면 다시 렌더링이 일어남. 따라서 내부 변수들은 초기화가 된다.

- ref에 저장한 값은 렌더링을 일으키지 않는다. 즉, ref의 값 변화가 일어나도 렌더링으로 인해 내부 변수들이 초기화 되는 것을 막을 수 있다.

-컴포넌트가 100번 렌더링되도 ref에 저장한 값은 유지된다.

 

** state는 리렌더링이 꼭 필요한 값을 다룰 때 쓰기
** ref는 리렌더링을 발생시키지 않는 값을 저장할 때 사용하기

 

 

예시

버튼을 누를때마다 ->  로직에 의해 반환된 값이 리랜더링이 되며 -> 화면에서 값이 계속 올라간다

ref로 설정된 버튼을 누를때마다 -> 값이 바뀌지만 ->  리랜더링(화면에 보여지는과정)이 되지 않아 -> 화면에서 값이 유지가 된다.

import { useRef } from 'react';
import { useState } from 'react';
import './App.css';


function App() {

  const [count, setCount] = useState(0);
  const countRef = useRef(0);


  const plusStateCountBtnHandler = () => {
    setCount(count+1);
  }

  const plusRefCountBtnHandler = () => {
    countRef.current++; // 1을 더한다
    console.log("countRef 버튼 눌린 횟수",countRef.current);
  }


  return (
    <div>
      <div style={{backgroundColor: "yellow",}}>
         state 영역입니다. {count} <br />
         <button onClick={plusStateCountBtnHandler}>state 증가</button>
      </div>
      <div style={{backgroundColor: "pink",}}>
        ref 영역입니다. {countRef.current} <br />
        <button onClick={plusRefCountBtnHandler}>ref 증가</button>
      </div>
    </div>
  );
}

export default App;

 

 

2. DOM 요소에 접근하는 방법

 

예시

: 처음 화면이 나올 때 아이디 입력창에 포커싱이 가게 한다

 

먼저, 아이디 입력창을 지정해야 한다! 즉, 이 입력창에 대한 레퍼런스를 갖고 있어야 한다.

  1. const idRef = useRef('');
  2. 입력창 input 태그 속성에 ref={idRef} 를 넣기
  3. useEffect 반환값에 idRef.current.focus() 넣기
import { useEffect } from 'react';
import { useState } from 'react';
import './App.css';


function App() {


  const idRef = useRef('');

  useEffect(()=>{
    idRef.current.focus(); //focus는 API 
  })

  return (
    <div>
      <div>
        아이디: <input type="text" ref={idRef}/>
      </div>
      <div>
        비밀번호: <input type="password"/>
      </div>
    </div>
  );
}

export default App;

 

 

연습

아이디가 10자리 입력되면 자동으로 비밀번호 필드로 이동하도록 하기

import { useEffect } from 'react';
import { useRef } from 'react';
import { useState } from 'react';
import './App.css';


function App() {

  const [id, setId] = useState('');
  const [pw, setPw] = useState('');
  const idRef = useRef('');
  const pwRef = useRef('')

  useEffect(()=>{
    idRef.current.focus(); //focus는 API 
  },[])

  useEffect(()=>{
    if(id.length >= 10){
      pwRef.current.focus();
    }
  },[id])

  return (
    <div>
      <div>
        아이디: <input value={id} onChange={(event)=> {
          setId(event.target.value);
        }} type="text" ref={idRef}/>
      </div>
      <div>
        비밀번호: <input value={pw} onChange={(event)=> {
          setPw(event.target.value);
        }} type="password" ref={pwRef}/>
      </div>
    </div>
  );
}

export default App;

 

 

onChange 함수안에 id.length ≥ 10 를 넣지 않은 이유?

batch 업데이트 방식을 사용하고 있기 때문이다. 

setId(event.target.value)에서 10번째 문자를 입력했을 때, 리액트는 그 아래 있는 함수를 아직 해결하지 않았기때문에 데이터 업데이트가 아직 안된상태로 그 아래 함수까지 모두 끝나야 if문의 id가 비로소 10으로 업데이트가 된다. 따라서 11자가 들어간 후에 비밀번호 입력창으로 커서가 포커싱되는 것이다. 따라서 앞으로 리액트의 이러한 배치 업데이트 방식을 잘 이해하고 로직을 짜야 한다.

728x90
반응형