far

useRef에 타입 주기 본문

Typescript

useRef에 타입 주기

Eater 2022. 12. 12. 04:15

타입스크립트를 사용하다보면 useRef(null)을 넣었을 때 React.MutableRefObject가 나오면서 에러가 나는 현상이 자주 발생하는데 원인을 몰라서 이것저것 넣어보다 정 안되면 타입에 any를 주고 넘어갔었다. 하지만 이번에 원인을 알게 되어 잊지 않기 위해 기록을 하고자 한다.

 

 

useRef가 받는 타입은 3가지가 있다.

// 1번
function useRef<T>(initialValue: T): MutableRefObject<T>;
// 2번
function useRef<T>(initialValue: T|null): RefObject<T>;
// 3번
function useRef<T = undefined>(): MutableRefObject<T | undefined>;

JSX에 연결할 용도라면 RefObject로 받고, 함수 안이나 ref.current 이런식으로 사용하고 싶다면 MutableRefObject로 받아야 한다.

 

 

설명을 위한 코드

const Test = () => {
	const [value, setValue] = useState('');
	const inputTest = useRef(null);

	const onSubmit = useCallback((e: React.FormEvent<HTMLFormElement>) => {
            e.preventDefault();
            setValue('');
            input.focus();
        }, []);
    
    return (
        <div>
            <form onSubmit={onSubmit}>
                <input
                    ref={inputTest}
                    value={value}
                />
                <button>버튼</button>
            </form>
        </div>
    );
}

 

위와 같은 코드를 치면 useRef때문에 ts에러가 발생한다. 그 이유는 JSX에 사용하기 위한 타입을 받아야 하는데 useRef가 처음에 null이다가 ref={ }가 실행되면서 값이 생기기 때문에 MutableRefObject가 받아져 에러가 발생하는 것이다.

 

const inputTest = useRef<HTMLInputElement>(null);

해결하는 방법은 이것. JSX에서 받도록 타입을 명시해준다. 참고로 여기에서 null을 안넣어주면 또 에러가 발생하는데 위의 2번 코드가 아니라, 타입이 일치한다고 인식해서 1번의 MutableRefObject를 받아버리기 때문이다.

 

const mro = useRef<number>(0);

이 코드처럼 타입(number)과 값(0)이 일치하면 1번에 걸린다.

Comments