Trouble Shooting

[React] Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?

dev_seon 2022. 10. 6. 10:43

1. 에러 발생

회원가입, 로그인 기능을 구현하기 위해 input 태그에 value를 입력받고, 필요한 경우 입력된 value에 대해 유효성 검사를 실시하고, 유효하지 않은 value가 입력되었을 시 에러 메시지를 출력하는 과정이 필요했습니다.

기능 구현 방법에 대해 고민하던 중 비제어 컴포넌트 방식으로 구현되어 있어 사용자의 입력에 따른 렌더링 횟수를 줄일 수 있는 React Hook Form을 사용하기로 결정했습니다.

 

각 페이지에 여러개의 input 태그가 존재했고, 구현해야 하는 각각의 input 태그의 형태와 기능이 유사했기 때문에 이를 재사용 컴포넌트로 만들고자 했습니다.

 

// Input.tsx; Warning 메시지 발생 코드

const Input = ({
	label,
	type = 'text',
	placeholder,
	...props
}: InputProps) => {
	const ref = useRef(null);
    
	return (
		<InputContainer>
			{label && <label>{label}</label>}
			<StyledInput type={type} placeholder={placeholder} ref={ref} {...props} />
		</InputContainer>
	);
};

export default Input;

 

React Hook Form은 비제어 컴포넌트를 기반으로 구현되어 있었고, 비제어 컴포넌트를 만들기 위해서는 ref를 사용해야 했기 때문에 위와 같이 ref를 선언하고, ref를 input 태그에 전달하여 컴포넌트를 만든 후 회원가입 페이지에 적용하자 다음과 같은 Warning 메시지가 발생했습니다.

 

Warning: Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?

 

Warning 메시지는 '함수 컴포넌트는 ref를 받을 수 없고, 해당 ref에 접근하려고 시도하면 실패할 것입니다. React.forwardRef()를 사용하려고 했나요?' 라는 의미였습니다.

 

2. 에러 해결

방법) React.forwardRef API 사용

// Input.tsx;

// React.forwardRef 적용
const Input = React.forwardRef<HTMLInputElement, InputProps>(
	({ type = 'text', placeholder, label, ...props }: InputProps, ref) => {
		return (
			<InputContainer>
				{label && <label>{label}</label>}
				<StyledInput
					type={type}
					placeholder={placeholder}
					ref={ref}
					{...props}
				/>
			</InputContainer>
		);
	}
);

Input.displayName = 'Input';

export default Input;

 

3. 고찰

본 Warning 메시지를 해결하며 공식문서를 통해 리액트에서 ref를 forwarding 하는 방법에 대해 학습할 수 있었습니다. 또한, 회원가입, 로그인 기능을 구현하기 위한 방법을 고민하고, 라이브러리의 공식 문서를 읽어보며 잘 알지 못했던 제어 컴포넌트, 비제어 컴포넌트의 개념에 대해 학습할 수 있는 시간이였습니다.