Pie_Archive

[React] Input: Text 훌륭하게 구현하기 본문

Front End

[React] Input: Text 훌륭하게 구현하기

코딩파이 2022. 5. 20. 01:36

0. 글을 쓰게 된 계기

 

최근 Test Code 관련 강의를 수강하던 중, 소스코드의 input 이 아래와 같이 구현 된 것을 발견했다.

const InputWithRef = () => {
  const inputRef = useRef();
  
  const addPost = (post) => {
    // 글 추가하는 함수
  }

  const onSubmit = () => {
    const { value } = inputRef.current;
    addPost(value)
  }

  return(
    <form>
      <input type="text"
        ref={inputRef}
        onSubmit={onSubmit}
      />
    </form>
  )
}

코드 자체는 문제가 없는데, 무엇이 문제여서 글을 쓰게 됬을까?


 

1. 배운거랑 달라요!

 

정말 이 문제 때문이었다.
조금 더 자세히 말하자면 나는 input창을 useState를 이용하여 구현했는데,
해당 코드에서는 useRef를 이용하여 구현했다는 것.

 

원래 내가 구현하던 방식의 코드를 보자.

const TestInputWithState = () => {
  const [input, setInput] = useState();
  
  const addPost = (post) => {
    // 글 추가하는 함수
  }

  const onSubmit = () => {
    addPost(input)
  }

  return(
    <form>
      <input type="text"
        onChange={(e) => setInput(e.target.value)}
        onSubmit={onSubmit}
      />
    </form>
  )
}

원래는 이런식으로

1. state를 생성하여 input의 value로 지정해주고

2. onChange를 이용하여 state를 변경시켜주고

3. onSubmit 호출시 input state 값 그대로 이용

 

이라는 절차대로 코드를 구현했었다.

이렇게 구현한 이유는 단순하다.

 

React를 처음 배울때 input창을 이런 식으로 구현했었다.

 

그러나 최근에 input창에 value로 state를 주면 input 창의 값을 바꿀 때 마다 재랜더링 되는게

성능적으로 무리가 없을까? 하여 조금 신경쓰였는데,

위 처럼 useRef를 사용하여 구현할 수 있다면

재랜더링 이슈를 방지할 수 있어서 찾아보았다.


 

2. 권고사항: useState를 쓰세요

 

해당 문제를 알아보다가, 프론트엔드 커뮤니티에 질문해 본 결과,

제어 / 비제어 컴포넌트에 대해 알게되었다

관련 링크

https://ko.reactjs.org/docs/uncontrolled-components.html

 

비제어 컴포넌트 – React

A JavaScript library for building user interfaces

ko.reactjs.org

요약하자면

input 창의 값이 바뀌는 상황에 대해서 비제어 컴포넌트인 useRef를 사용하게 되면 몇몇 오류가 발생할 수 있기에

재랜더링 이슈가 있다 하더라도 제어 컴포넌트인 useState 형식으로 Input창을 구현하는걸 권고하고 있다.


 

3. ...그럼 무조건 useState를 사용해야 해?

 

사실 그건 아니라고 한다.

위 공식문서에서도 권고사항이고, 또 확실히 state는 재랜더링 이슈는 있기도 해서

useRef를 사용하여 Input창을 구현해도 되는 상황이 있다.

 

1. 비밀번호 일치여부 검사, 입력값 길이 검사 등 : input의 값이 바뀔 때 마다 특정 로직을 수행해야 할 때

이럴땐 묻고 따지지도 말고 state를 사용하자.

확실하게 value 값을 제어하고, 이를 통해 로직을 구현할 수 있기 때문에 재랜더링 이슈가 있더라도 state를 사용하는게 맞다.

 

2. 검색창 검색, 문서제출 등 : input값의 로직이 한번만 수행될 때 

글을 쓰거나 네이버 검색창 같은, submit 하는 순간에서만 로직이 일어날 때는 비제어 컴포넌트인 useRef를 사용해도 된다고 한다. 앞서 예제코드 같은 상황 말이다.

 

결국, 특정 상황에서 권고사항을 따르느냐, 성능에 좀 더 집중을 하느냐를 적절히 판단해서 구현해야 하는 것인데,

정말 리액트는 배울수록 어려운 것 같다.

 

추가로, 재랜더링 이슈는  throttle 이나 debounce 라는 걸로 단점을 보완 할 수 있다고 한다.

 

나중에 좀 더 찾아봐야겠다.

 

틀린 문제의 지적사항은 언제나 환영입니다 :)