처음에는 컬러인풋을 클릭해 지정하는 방법만 있었다
하지만 이 방법은 사용자에게(나) 너무 귀찮은 방법이었다
그래서 또 다른 텍스트인풋을 만들어 헥스코드를 입력하면
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>" {nowColor} "</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를 적용하기!
그러면 멈춘 뒤 다시 입력해도 워닝이 안 뜬다❤️