관리 메뉴

공부기록용

React숙련주차05(React Hooks - useRef💫) 본문

📚강의록📚/스파르타)React

React숙련주차05(React Hooks - useRef💫)

과부하가즈아 2023. 6. 29. 23:29

🔴useRef

🔴useRef는 2가지 용도

🔴state와 ref의 차이점


💫저장공간으로서의 useRef, DOM요소 접근 방법으로서의 useRef

 

useRef

DOM 요소에 접근할 수 있도록 하는 React Hook, 리액트에서도 DOM을 선택해야 할 상황이 생기고 그때 사용한다.

ref : reference_어떤 것의 참조 정도로 이해하기
const 변수 = useRef("초기값");
import "./App.css";
import { useRef } from "react";

function App() {
  const ref = useRef("초기값");
  console.log("ref", ref);

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

export default App;


ref로 선언해 놓은 값에 접근해서 값을 바꿔줄 수도 있다. 

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

function App() {
  const ref = useRef("초기값");
  console.log("ref 1", ref);

  ref.current = "바꾼 값";
  console.log("ref 1", ref);

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

export default App;


💫💫설정된 ref 값은(const ref로 선언)컴포넌트가 계속해서 렌더링 되어도 unmount 전까지 값을 유지한다.(즉 이 컴포넌트가 죽기 전까지는 값을 유지한다.)

 

이러한 특징 때문에 useRef는 2가지 용도로 사용한다.

  1. 저장공간으로써 사용된다.
    • state와 비슷한 역할을 해요. 다만 state는 변화가 일어나면 다시 렌더링이 일어난다. 내부 변수들은 초기화가 된.(함수형으로 함수가 다시 그려진다.)
    • ref에 저장한 값은 렌더링을 일으키지 않는다. 즉, ref의 값 변화가 일어나도 렌더링으로 인해 내부 변수들이 초기화 되는 것을 막을 수 있다.
    • 컴포넌트가 100번 렌더링 → ref에 저장한 값은 유지된다.
    • 그래서!
      • state는 리렌더링이 꼭 필요한 값을 다룰 때 쓰면 된다.
      • ref는 리렌더링을 발생시키지 않는 값을 저장할 때 사용한다.(내부적으로 보지 않아도 되는 값들이 있다)
  2. DOM
    • 특정 input이 focusing 돼야 한다면 useRef를 사용하면 됩니다.

리렌더링이 된다 = 함수가 다시 호출된다 = 내부 변수가 다시 쫙 초기화된다


state와 ref의 차이점

 

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

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

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

  const plusRefCountButtonHandler = () => {
    countRef.current++;
  };

  return (
    <>
      <div>
        state 영역입니다. {count} <br />
        <button onClick={plusStateCountButtonHandler}>state 증가</button>
      </div>
      <div>
        ref 영역입니다. {countRef.current} <br />  
        <button onClick={plusRefCountButtonHandler}>ref 증가</button>
      </div>
    </>
  );
}

export default App;

> countRef.current -> 위에서 선언한 useRef로 countRef는 배열이 된다. 

> 그리고 그 배열은 {current: 0}으로 나타나게 된다.

> 그래서 배열의 요소를 가져와야 하는 것이므로 countRef.current가 되는 것이다.


> ref에 저장한 값은 렌더링이 일어나지 않는다. 즉, 값의 변화가 일어나도 렌더링으로 인해 내부 변수들이 초기화 되지 않느다. 변화가 없다는 의미


import { useEffect, useRef } from "react";
import "./App.css";

function App() {
  const idRef = useRef("");

  // 화면이 렌더링이 될 때
  // 아이디에 포커싱 되게하자
  // 즉, 고정으로 해줘야 되니까 useRef를 사용해 볼 수 있다.
  useEffect(() => {
    idRef.current.focus();
    // idRef. 하는 순간 아이디 input태그가 지정이 된다.
  }, []);

  return (
    <>
      <div>
        아이디 : <input type="text" ref={idRef} /> 
        {/* 1. input태그 안에 ref의 속성이 있다
        그 ref속성안에 useReffh 선언한 변수_idRef를 넣어주면
        이 input태그와 useRef가 연결이 됬다고 할 수 있다. */}
      </div>
      <div>
        비밀번호 : <input type="password" />
      </div>
    </>
  );
}

> 아이디 input태그로 자동 포커싱 됨


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

function App() {
  const idRef = useRef("");
  const pwRef = useRef("");

  const [id, setId] = useState("")

  // const idChangeHandler = function(event){
  //   setId(event.target.value);
  // };

  // id로 포커싱되는 useEffect
  useEffect(() => {
    idRef.current.focus();
  }, []);

  // 리액트 컴포넌트가 렌더링될 때마다 특정 작업을 수행하도록 설정할 수 있는 Hook이니까
  // 여기서 id가 10자리가 넘어가면 pw로 포커싱이 움직이게 함
  useEffect(function(){
    if(id.length >= 10){
      return pwRef.current.focus();
    }
  },[id]); // [id]를 넣어줌으로써 아이디의 상태가 계속 바뀌는 것을 확인해 나갈 수 있다.

  return (
    <>
      <div>
        아이디 : 
        <input 
        type="text" 
        ref={idRef} 
        value={id}
        onChange={function(event){
          return setId(event.target.value)

          // if(id.length >= 10){
          //   pwRef.current.focus();
          // }
          // 위에서 useEffect를 사용하지 않고 이렇게도 해줄 수 있다 하지만
          // react의 속성인 배치성때문에 변화가 일어나는 setId가 10->11되는 순간이기때문에
          // 즉 9->10이 되는 순간은 아직 반영이 안된것/10->11
          // 11번째의 수를 입력할 때에서야 pw로 포커스가 넘어가게 된다.

        }} /> 
      </div>

      <div>
        비밀번호 : <input type="password" ref={pwRef} />
      </div>
    </>
  );
}

export default App;

10자리째에 pw로 포커싱이 넘어감

Comments