디바운싱 적용해보기

이서현·2022년 7월 9일
1
post-thumbnail

  • input[type="color"] === 컬러인풋
  • input[type="text"] === 텍스트인풋

달력에 배경색 지정 기능을 만들고 있었다

처음에는 컬러인풋을 클릭해 지정하는 방법만 있었다

하지만 이 방법은 사용자에게(나) 너무 귀찮은 방법이었다
그래서 또 다른 텍스트인풋을 만들어 헥스코드를 입력하면
setState가 실행되고 저장된 state가 컬러인풋 value가 되는 코드를 작성했다

const [nowColor, setNowcolor] = useState(clickDate.todayBg || '#ffffff')
const handleColor = (e: ChangeEvent<HTMLInputElement>) => setNowcolor(e.currentTarget.value)
.
.
.
<input type='color' value={nowColor} onChange={handleColor} />
<input type='text' value={nowColor} onChange={handleColor} />

그런데 텍스트인풋에 입력을 하니 형식에 맞지 않다고 워닝이 떴다

e.currentTarget.value값이 실시간으로 반영되어 워닝이 생긴 것 같다
이럴 때 디바운싱을 적용하면 워닝이 안 생길 것 같다(아니었다...)

디바운싱이란?

연이어 호출되는 함수들 중 마지막 함수(또는 제일 처음)만 호출하도록 하는 것

디바운싱 적용

  const [nowColor, setNowcolor] = useState(clickDate.todayBg || '#ffffff')
  const [hexadecimalColor, setHexadecimalColor] = useState(nowColor)
  
  const handleColor = (e: ChangeEvent<HTMLInputElement>) => setHexadecimalColor(e.currentTarget.value)
  
  useEffect(() => {
    const debounce = setTimeout(() => {
      return setNowcolor(hexadecimalColor)
    }, 2000)
    return () => {
      clearTimeout(debounce)
    }
  }, [hexadecimalColor])

.
.
.
<input type='color' value={nowColor} onChange={handleColor} />
<input type='text' value={hexadecimalColor} onChange={handleColor} />
<p>&quot; {nowColor} &quot;</p>

화면에 표시하기 위해 hexadecimalColor라는 state를 하나 더 만들었다
1. 텍스트인풋에 입력한다
2. handleColor가 실행된다
3. hexadecimalColor가 변경된다
4. hexadecimalColor가 변경되면 uesEffect가 실행된다
5. 2초 뒤 setNowcolor(hexadecimalColor)가 실행된다
✻실시간으로 바뀌는 게 아니라 입력한 마지막 값이 state(nowColor)가 된다
6. 바로 clearTimeout(debounce)이 실행된다

근데 한 번에 값을 입력하면 문제가 되진 않지만
내가 입력을 하는 도중 멈춘 뒤 2초가 지나면 다시 워닝이 뜬다...

내가 원한 건 저 워닝이 아예 안 뜨는 것!
그래서 조건을 추가했다

  useEffect(() => {
    const debounce = setTimeout(() => {
      // 추가 조건
      if (hexadecimalColor.length < 6) return setNowcolor(nowColor)
      return setNowcolor(hexadecimalColor)
    }, 700)
    return () => {
      clearTimeout(debounce)
    }
  }, [hexadecimalColor, nowColor])

hexadecimalColor가 6자리 이하일 땐 바뀌기 전 nowColor를 적용하기!
그러면 멈춘 뒤 다시 입력해도 워닝이 안 뜬다❤️

참고 - Debounce 와 Throttle 리액트로 구현하기

profile
🌿💻💪🧠👍✨🎉

0개의 댓글