[react] useState대신에 useRef를 사용하여 불필요한 재랜더링을 없애기

Hwanhoon KIM·2023년 7월 30일
0

Input에 useState()대신에 useRef만 사용하기

보통 useState를 사용해서 input을 상대하면, 계속 그 컴포넌트가 쓸때없이 랜더링되는 현상이 발생한다.

그래서 해당 input의 값만 useRef를 통해서 string으로 받아낸다.

여기서 가장 중요한 것은 useRef를 사용한 것이 그냥 string 값일 뿐이지 그 input을 참조하는 것은 아니라는 것이다.

그래서 다음과 같은 로직이 나올 수 있다.

const TodoInput: React.FC = (): JSX.Element => {
  const todoVal = useRef<string>('')
  const todoInputRef = useRef<HTMLInputElement>(null)
	
  // 작성하기
  const postClickHandler = (): void => {
    if (!todoVal.current || todoInputRef.current === null) {
      alert('할 일을 적어주세요.');
      todoInputRef.current?.focus();
      return;
    }
    // input값과 id를 저장
    const newData: T_todo = {
      id: Date.now(),
      todo: todoVal.current,
    };
    dispatch(postTodo(newData));
    todoVal.current = '';
    todoInputRef.current.value = '';
  };

	return (
    <StyledDiv>
      <input
        type="text"
        ref={todoInputRef}
        onChange={(e) => (todoVal.current = e.target.value)}
      />
      <button onClick={postClickHandler}>작성하기</button>
    </StyledDiv>
  );
}

코드에서 todoVal은 그저 string으로 input값을 참조하는 것이고 실제적으로 inputonChange될 때마다 값이 업데이트는 되고 있지만[1], 컴포넌트가 랜더링되지는 않는다.

또, UX를 위해서 input이 빈 칸일 때 사용자가 버튼을 누르면, 할 일을 적어주세요라는 알림과 함께 해당 inputfocus를 주는 기능에서는 직접 todoInputRef를 통해 input을 참조하고[2], todoInputRef.current?.focus();를 통해서 focus()blur() 같은 메소드 사용이 가능하다.

결론

이로써, 다음부터 input을 쓸 때는 불필요한 재랜더링을 막기위해서 useRef로 사용해봐야겠다.

[1]: onChange={(e) => (todoVal.current = e.target.value)}, 즉 input이 변경될 때 마다, todoVal의 current값은 e.target.value(input의 값)입니다. 라고 해주는 것이다.

[2]: <input ref={todoInputRef}/>

learned by Sakura Dev, https://youtu.be/EqbwHO6Vgbg?t=909
profile
Fullstack Developer, I post about HTML, CSS(SASS, LESS), JavaScript, React, Next, TypeScript.

0개의 댓글