⚛️ 기본 환경: IDE: VS code, Language: React
발생 Error
React에서 다음 Source Code를 실행할 경우,
1
2
3
4
5
6
7
8
9
10
11
|
const submitHandler = (event) => {
event.preventDefault();
if(formIsValid){
authCtx.onLogin(emailState.value, pwdState.value);
} else if(!emailIsValid) {
emailInputRef.current.activate();
} else {
pwdInputRef.current.activate();
}
};
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
const Login = (props) => {
const emailInputRef = useRef();
const submitHandler = (event) => {
event.preventDefault();
if(formIsValid){
authCtx.onLogin(emailState.value, pwdState.value);
} else if(!emailIsValid) {
emailInputRef.current.activate();
} else {
pwdInputRef.current.activate();
}
};
return (
<Card className={classes.login}>
<form onSubmit={submitHandler}>
<Input
ref={emailInputRef}
id="email"
label="E-Mail"
type="email"
isValid={emailIsValid}
value={emailState.value}
onChange={emailChangeHandler}
onBlur={validateEmailHandler}
/>
<div className={classes.actions}>
<Button type="submit" className={classes.btn}>
Login
</Button>
</div>
</form>
</Card>
);
};
|
🚨 다음과 같은 경고 발생
Warning: Function components cannot be given refs.
Attempts to access this ref will fail.
Did you mean to use React.forwardRef()?
발생 원인
함수 컴포넌트는 ref를 받을 수 없음, 즉 props 객체는 ref prop을 받아들이지 않음
해결 방법
useImperativeHandler Hook + forwardRef 사용
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
const Input = React.forwardRef((props, ref) => {
const inputRef = useRef();
const activate = () => {
inputRef.current.focus();
};
useImperativeHandle(ref, () => {
return ({
focus: activate
});
});
return (
<div
className={`${classes.control} ${
props.isValid === false ? classes.invalid : ""
}`}
>
<label htmlFor={props.id}>{props.label}</label>
<input
ref={inputRef}
type={props.type}
id={props.id}
value={props.value}
onChange={props.onChange}
onBlur={props.onBlur}
/>
</div>
);
})
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
const Login = (props) => {
const emailInputRef = useRef();
const submitHandler = (event) => {
event.preventDefault();
if(formIsValid){
authCtx.onLogin(emailState.value, pwdState.value);
} else if(!emailIsValid) {
emailInputRef.current.focus();
} else {
pwdInputRef.current.focus();
}
};
return (
<Card className={classes.login}>
<form onSubmit={submitHandler}>
<Input
ref={emailInputRef}
id="email"
label="E-Mail"
type="email"
isValid={emailIsValid}
value={emailState.value}
onChange={emailChangeHandler}
onBlur={validateEmailHandler}
/>
<div className={classes.actions}>
<Button type="submit" className={classes.btn}>
Login
</Button>
</div>
</form>
</Card>
);
};
|
useImperativeHandler(프로퍼티를 부여할 ref, 객체(추가하고싶은 prop 정의)를 리턴하는 함수)
→ React.forwardRef*((props, ref), () => {}): ref 인자 추가하여 forwardRef 선언
→ 객체 정의에 맞춰 작동시키고자하는 함수 호출
* forwardRef: 상위 컴포넌트에서 전달받은 ref를 하위 컴포넌트로 전달하는 역할
참고 자료