useRef hook

현우.·2024년 8월 24일
0

react

목록 보기
2/6
post-thumbnail

useRef hook

useRef는 렌더링에 필요하지 않은 값을 참조할 수 있게 해주는 React Hook

참조 선언

import { useRef } from 'react';
const ref = useRef(initialValue);

useRef: 단일 프로퍼티(current)를 가진 객체를 반환한다.
initialValue : 참조 객체의 프로퍼티인 current에 처음에 지정할 값이다.

function MyComponent() {
  const inputRef = useRef(null);
  
  function handleClick() {
    inputRef.current.focus();
  }
  
   // ...
  return <input ref={inputRef} />;
}

current initialValue: 처음에는 전달한 것으로 설정된다.
나중에 다른 것으로 설정할 수 있다.
만약 참조 객체를 JSX 노드의 속성인 ref에 넣어 React에 전달하면
React가 해당 current속성을 설정한다.(DOM제어)

  • inputRef.current = <input ref={inputRef} />

활용

ref를 사용하여 값 참조

ref의 특징

  1. 정보가 공유되는 외부 변수와 달리 각 컴포넌트에 로컬로 저장된다.
  2. 렌더링 시마다 재설정되는 일반변수와 다르게 정보를 저장할 수 있다.
  3. 그러나 리렌더링을 일으키는 state 변수와 달리 변경해도 리렌더링을 일으키지 않는다.
  4. 즉, 참조는 구성 요소의 시각적 출력에 영향을 미치지 않는 정보를 저장하는 데 좋다.
  5. 참조 내부의 값을 업데이트하려면 해당 current속성을 수동으로 변경해야 한다.
import { useRef } from 'react';

function Stopwatch() {
  const intervalRef = useRef(0);
  // ...
  
  function handleStartClick() {
    intervalRef.current = setInterval(() => {
      // ...
    }, 1000);
  }
  
  function handleStopClick() {
    clearInterval(intervalRef.current);
  }
}

useRef를 사용하여 값을 참조하는 예 ex)Click Counter

import { useRef } from 'react';

export default function Counter() {
  let ref = useRef(0);

  function handleClick() {
    ref.current += 1
    alert('You clicked ' + ref.current + ' times!');
  }

  return (
    <button onClick={handleClick}>	
      Click me!
    </button>
  );
}

주의📌

랜더링하는동안 ref.current를 쓰거나 읽지 말기!

  • React는 구성 요소의 본문이 순수 함수처럼 동작할 것으로 기대하기 때문에 렌더링하는 동안 참조를 읽거나 쓰면 이러한 기대가 깨진다.
function MyComponent() {
  // ...
  // 🚩 Don't write a ref during rendering
  myRef.current = 123;
  // ...
  // 🚩 Don't read a ref during rendering
  return <h1>{myOtherRef.current}</h1>;
}
  • 대신 이벤트 핸들러나 효과에서 참조를 읽거나 쓸 수 있다.
function MyComponent() {
  // ...
  useEffect(() => {
    // ✅ You can read or write refs in effects
    myRef.current = 123;
  });
  // ...
  function handleClick() {
    // ✅ You can read or write refs in event handlers
    doSomething(myOtherRef.current);
  }
  // ...
}
  • 렌더링 중에 무언가를 읽거나 써야 하는 경우 대신 state를 사용해라!
  • 이러한 규칙을 어겨도 컴포넌트가 여전히 작동할 수 있지만 React에 추가하는 대부분의 새로운 기능은 이러한 기대에 의존하기 때문에 규칙을 지키는것이 좋다.

ref를 사용하여 DOM 조작

ref를 이용해 DOM을 조작하는 것이 일반적이다.

useRef를 사용하여 DOM을 조작하는 예 ex) 텍스트 입력에 초점맞추기

import { useRef } from 'react';

export default function Form() {
  //1. 먼저, 초기값을 갖는 참조 객체를 선언
  const inputRef = useRef(null);

  function handleClick() {
    // 3. React는 ref 객체의 current속성을 <input>노드로 설정한다.
    // 4. js함수인 focus()를 사용해 <input>노드를 focus 시킬 수 있다.
    inputRef.current.focus();
  }

  return (
    <>
    //2. 조작하려는 DOM 노드의 JSX에 대한 속성 으로 참조 객체를 전달
      <input ref={inputRef} />
      <button onClick={handleClick}>
        Focus the input
      </button>
    </>
  );
}

forwardRef

forwardRef참조를 통해 구성 요소가 부모 구성 요소에 DOM 노드를 노출할 수 있다.

const SomeComponent = forwardRef(render)

  • forwardRef()구성 요소가 참조를 수신하고 자식 구성 요소로 전달하도록 호출한다.
  • render: 컴포넌트의 렌더 함수입니다. React는 props와 ref컴포넌트가 부모로부터 받은 것을 사용하여 이 함수를 호출한다. 반환하는 JSX는 컴포넌트의 출력이 된다.

ex.1)

const MyInput = forwardRef(function MyInput(props, ref) {
    const { label, ...otherProps } = props;
  return (
    <label>
      {label}
      <input ref={ref} {...otherProps}  />
    </label>
  );
});

ex.2)

const MyInput = forwardRef(function MyInput({label,result},ref) {
  return (
    <label>
      {label}
      <input ref={ref} />
    </label>
  );
});
  • props: 부모 컴포넌트로부터 전달된 props.
  • ref: ref부모 컴포넌트에서 전달한 속성. 는 ref객체 또는 함수가 될 수 있다.
  • ref는 render 함수의 2번째 인자로 받아야한다.
function Form() {
  const ref = useRef(null);

  function handleClick() {
    ref.current.focus();
  }

  return (
    <form>
      <MyInput label="Enter your name:" ref={ref} />
      <button type="button" onClick={handleClick}>
        Edit
      </button>
    </form>
  );
}
  • 부모 구성 요소는 다음에 의해 노출된 DOM 노드 Form 에 액세스할 수 있다.

즉 fowardRef를 사용하면 부모 컴포넌트에서 자식컴포넌트로 참조를 전달하여 자식 컴포넌트의 DOM노드를 참조하여 통제할 수 있는 기능이다.

profile
학습 기록.

0개의 댓글