728x90
const AuthInput: React.FC<AuthInputType> = ({ title, password, setValue }) => {
    const [isVisible, setIsVisible] = useState(password);
    const [inputValue, setInputValue] = useState('');

    const toggleIsPassword = () => {
        setIsVisible(!isVisible);
    };

    const onChangeInput = (e: ChangeEvent<HTMLInputElement>) => {
        setValue(e.target.value);
    };

 로그인 및  회원가입에 사용할 인풋창을 위와 같은 로직으로 구현하였다.
문제가 없어 보일 수 있지만, 성능적으론 굉장히 문제가 있는 코드이다.

리익트 리랜더링 조건으로는  

  1. state 변경이 있을 때
  2. 새로운 props이 들어올 때,
  3. 부모 컴퍼넌트가 렌더링 될 때
  4. props가 업데이트 될 때

4가지로 주로 꼽는다.

 

위 코드와 같이 부모 컴퍼넌트의 setter를 받는 컴퍼넌트는 부모 컴퍼넌트의 state를 변경 시킨다.
이는 부모 컴퍼넌트의 리렌더링을 유발하고 이에 의해서, 부모 컴퍼넌트 아래의 모든 컴퍼넌트를 리 랜더링 시킨다.

따라서 리랜더링을 줄이기 위해서 debounce를 사용하여서 제어하려고 한다.
debounce는 지정한 delay시간안에 추가적인 매개변수값의 변화(입력값)가 없는 경우에만 return 하게 하여 
한번에 여러 글자를 일어나는 경우 렌더링 횟수를 줄이기 위해서 사용한다.
https://dev.to/manishkc104/debounce-input-in-react-3726

 

Debounce Input in React

Debouncing an input is a technique used to improve web application performance and user experience....

dev.to

위 게시글을 보면 우선 자식 컴퍼넌트로 입력값을 받고 이 값의 변화를 useEffect로 인지하고, setTimeout과 clearTImeout을 활용하여  제어하려한다.

React.useEffect(() => {
  const delayInputTimeoutId = setTimeout(() => {
    setDebouncedInputValue(inputValue);
  }, 500);
  return () => clearTimeout(delayInputTimeoutId);
}, [inputValue, 500]);

이를 활용하여 내 코드도 리랜더링을 제어하려한다.

하지만 디바운스의 경우 범용성이 높기 떄문에 커스텀훅으로 만들 것 이다.


import { useEffect, useState } from 'react';

export const useDebounce = (value: string, delay: number) => {
	const [debounceValue, setDebounceValue] = useState(value);
	useEffect(() => {
		const handler = setTimeout(() => {
			setDebounceValue(value);
		}, delay);

		return () => {
			clearTimeout(handler);
		};
	}, [value, delay]);

	return debounceValue;
};

이후  input의 값과 딜레이를 훅에 인수로 전달할 것이다.
그리고 useEffect를 통해서 debounceValue가 변할 떄마다 부모 컴퍼넌트의 setter를 통해서 값을 할당하면 된다.

const AuthInput: React.FC<AuthInputType> = ({ title, password, setValue }) => {
	const [inputValue, setInputValue] = useState('');

	const onChangeInput = (e: ChangeEvent<HTMLInputElement>) => {
		setInputValue(e.target.value);
	};
	const debouncedValue = useDebounce(inputValue, 300);

	useEffect(() => {
		if (debouncedValue) {
			setValue(debouncedValue);
		}
	}, [debouncedValue, setValue]);

	return (
		<AuthInputWrapper>
			<AuthInputTitle>{title}</AuthInputTitle>
			<AuthInputContainer>
				<AuthInputSheet type={isVisible ? 'password' : 'text'} onChange={onChangeInput} />



사실 위 커스텀훅을 만들고, onChangeInput 내에서 훅을 사용하려다가  일반 함수내에서 훅을 사용하려다가 훅 규칙을 위반해서 에러도 겪었었지만, 결국 완성,,

+ Recent posts