고양이와 코딩

[React] - useState와 useRef 본문

react

[React] - useState와 useRef

ovovvvvv 2024. 3. 6. 14:28
728x90

투두리스트를 만들때도, 강의를 들을때도 useState를 잘 쓰다가 갑자기 useRef를 사용하는 경우가 있습니다

대부부 궁금해하지도 않고 그런가보다~ 하고 넘어갔는데요

 

스터디를 하는 중 친구가 useRef 왜 사용했어? 묻자마자

꿀먹은 벙어리가 되어버렸기에.......

 

 

useState

컴포넌트가 렌더링 사이의 일부 정보를 "기억" 해야 할 때 state 변수를 사용합니다.

'useState' 훅은 함수 컴포넌트 내에서 상태를 추가하고 관리할 수 있게 해줍니다. 이 상태는 컴포넌트의 렌더링과 관련이 있으며, 상태가 변경될 때 마다 컴포넌트가 다시 렌더링됩니다.

 

  1. 상태 값이 변할 때마다 컴포넌트가 다시 렌더링됨
  2. 함수 컴포넌트 내에서 여러 상태 값을 가질 수 있음
  3. 상태 값은 렌더링 중에 읽고 변경할 수 있음
  4. 상태 값은 렌더링과 함께 컴포넌트 내에서 지속되는 데이터를 저장하는 데 사용됨

 

스냅샷으로써의 state 얘기를 해 보겠습니다.

이 예제에서 handleClick 함수의 실행이 한 번 끝나도 0이 3이 되지 않는다는건 알고 있었지만,

왜 3이 되지 않는데? 라는 질문에는 대답하기 어려웠습니다.

const [index, setIndex] = useState(0);

function handleClick() {
	setIndex(index + 1); // 현재 index는 0이고 다음 인덱스는 1이야
	setIndex(index + 1); // 현재 index는 0이고 다음 인덱스는 1이야
	setIndex(index + 1); // 현재 index는 0이고 다음 인덱스는 1이야
}

위 코드가 여전히 1이 되는 이유는, setState 함수가 비동기적으로 작동하기 때문입니다!

setIndex 함수의 호출이 순차적으로 실행되는게 아니라, 동시에 이전 상태 값을 기반으로 실행되기 때문에 
주석에서 말한것처럼 이전 상태 값(0)을 기반으로 실행되므로, 결과적으로 setIndex값이 1로 끝나게 됩니다

const [index, setIndex] = useState(0);

function handleClick() {
      setIndex(prevIndex => prevIndex + 1);
      setIndex(prevIndex => prevIndex + 1);
      setIndex(prevIndex => prevIndex + 1);
}

코드를 이렇게 수정하면 이전 상태 값을 기반으로 업데이트 되므로 원하는대로 작동합니다!

 

useRef

'useRef' 훅은 DOM 요소 또는 다른 값을 참조하는데 사용됩니다. 이는 useState와는 다르게 컴포넌트의 렌더링과 관련이 없으며, 값이 변경되어도 컴포넌트가 다시 렌더링 되지 않습니다

 

  1. 값이 변경되어도 컴포넌트가 다시 렌더링되지 않음
  2. 함수 컴포넌트 내에서 참조를 생성하고 유지할 수 있음
  3. 참조를 사용하여 DOM 요소에 접근할 수 있음
  4. 렌더링과 관련이 없는 데이터를 저장하거나 전달할 때 사용됨
import React, { useRef } from 'react';

const InputFocus = () => {
  const inputRef = useRef<HTMLInputElement | null>(null);

  const focusInput = () => {
    if (inputRef.current) {
      inputRef.current.focus();
    }
  };

  return (
    <div>
      <input ref={inputRef} type="text" />
      <button onClick={focusInput}>Focus Input</button>
    </div>
  );
};

export default InputFocus;

inputRef.current를 사용하여 현재 참조된 DOM 요소에 접근합니다. 그리고 focus()를 사용하여 해당 입력 요 소에 포커스를 설정합니다

여기에서 inputRef의 current 속성은 변경되는 값을 가지고 있지만, 컴포넌트가 렌더링되고 나면 inpufRef.current는 실제 DOM 입력 요소를 가리키게 됩니다. 

 

중요한점은 `inputRef.current`의 값은 `useRef` 훅이 사용된 컴포넌트의 렌더링과는 관련이 없으며, 렌더링 사이클에 영향을 주지 않는다는 점입니다!

DOM 요소에 대한 참조를 유지하고, 업데이트 할 수 있습니다.

 

 

어떤 것을 사용해야 할까?

  1. useState를 사용해야 하는 경우:
    • 컴포넌트의 렌더링과 관련된 상태를 관리해야 할 때.
    • 상태 값이 변경될 때 컴포넌트가 다시 렌더링되어야 할 때.
  2. useRef를 사용해야 하는 경우:
    • DOM 요소에 직접 접근해야 할 때.
    • 함수 컴포넌트 내에서 컴포넌트의 렌더링과 관련 없는 값을 유지하고 싶을 때.
    • 이전 값과 새로운 값을 비교하고자 할 때.

예를 들어, 입력 요소에 직접 접근하거나, 이전 값과 새로운 값을 비교하려면 useRef를 사용하는 것이 좋습니다.

컴포넌트의 렌더링과 관련된 상태를 관리해야 한다면 useState를 사용하세요.

 

 

 

https://react-ko.dev/learn/referencing-values-with-refs#differences-between-refs-and-state