초보 개발자의 성장 일기
로그인 입력폼이 유효하지 않을 때 본문
로그인 폼을 구현하다가 사용자가 로그인할 때 입력폼에 아무것도 입력되지 않으면
- 로그인 버튼을 비활성화를 해야할지
- 입력 폼에 focus를 주어야 할지
고민이 들었다.
입력을 안했을 때 버튼 자체가 비활성화가 되는것도 좋지만,
로그인 버튼을 눌렀을 때 어떤 입력폼에 입력을 해야할지 focus를 주면 사용자 입장에서 더 편리할 수도 있겠다는 생각이 들었다.
무엇을 입력해야 하는지 알 수 있고,
focus를 주면 사용자가 바로 입력하기 편리할 것 같다는 생각이 들었다.
1. focus를 줄 수 있는 activate 함수 만들기
const Input = (props) => {
const inputRef = useRef();
const activate = () => {
inputRef.current.focus();
};
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>
);
};
|
email과 password는 각각 재사용이 가능한 Input 컴포넌트로 관리되어 있다.
이 컴포넌트 안에 focus를 줄 수 있는 activate 함수를 만들었다.
const emailInputRef = useRef();
const passwordInputRef = useRef();
const submitHandler = (event) => { event.preventDefault();
if (formIsValid) {
authCtx.onLogin(emailState.value, passwordState.value);
} else if (!emailIsValid) {
emailInputRef.current.activate();
} else {
passwordInputRef.current.activate();
}
};
|
submitHandler 함수, 즉 로그인 버튼을 눌렀을 때 실행될 함수에 email 또는 password가 유효하지 않을 때를 구분해서 activate함수가 실행될 수 있게 해 주었다.
하지만 이렇게 하면 오류를 직면하게 된다.
함수컴포넌트는 ref를 받을 수 없다고 한다.
props 객체에서 ref프롭을 받아드리지 못하는 것이다.
이 문제를 해결하기 위한 훅이 있다.
2. useImperativeHandle 사용
import { useImperativeHandle } from "react";
|
react 내장 훅인 useImperativeHandle을 사용하는 것이다.
이 훅을 사용하면 컴포넌트나 컴포넌트 내부에서 오는 기능을 명령적으로 사용할 수 있게 해준다.
일반적인 state 프롭 관리를 통하지 않고
부모 컴포넌트의 state를 통해 컴포넌트를 제어하지 않고
프로그래밍적으로 컴포넌트에서 무언가를 직접 호출하거나 조작해서 사용하게 해 준다.
그래서 이 훅은 자주 사용하지 않는것이 좋다고 한다.
사용 방법은
useImperativeHandle(ref, () => {
return {
focus: activate,
};
});
|
1) 첫번째 매개변수에는 Input 매개변수로 props와 ref를 인수로 받아온다.
ref를 외부에서 설정해야 하는 경우 이것을 설정했다는 것을 확실히 하기 위해
부모 컴포넌트에는 ref 프롭을 추가하고 바인딩하면 ref로 받아와서 연결을 해 준다.
🔍 바인딩이란?
HTML에 원하는 데이터를 일치하게 만드는 것이다.
ref를 props와 같이 받아오면서 바인딩을 해 주는 것이다.
이 ref를 천번째 매개변수로 넣어준다.
2) 두번째 매개변수에는 함수를 넣어 준다.
이 함수는 외부에서 사용할 수 있는 모든 데이터를 포함한 객체를 반환해야 한다.
외부에서 접근할 수 있어야 하는 것을 가리킨다.
const Input = React.forwordRef((props, ref) => {
|
두번째 인수 ref를 활성화 시키기위해서 React.forwardRef로 감싸주어야 한다.
(react를 import해야 사용할 수 있다.)
Input은 ref에 바인딩 될 수 있는 리액트 컴포넌트가 된다.
const submitHandler = (event) => {
event.preventDefault();
if (formIsValid) {
authCtx.onLogin(emailState.value, passwordState.value);
} else if (!emailIsValid) {
emailInputRef.current.focus();
} else {
passwordInputRef.current.focus();
}
};
|
이전에 작성해 주었던 함수에서 activate를 focus로 바꿔준다.
이렇게 하면 email input값이 비어있거나 유효하지 않을 때 로그인 버튼을 누르면 email input에 포커스가 맞춰지고
password가 비어있거나 유효하지 않을 때는 password input에 포커스가 맞춰진다.
'Development > React JS' 카테고리의 다른 글
메뉴 hover시 border-bottom넣을 때 글자 움직임 (0) | 2024.01.23 |
---|---|
데이터 fetch 후 map을 하면 읽을 수 없는 이유 (0) | 2024.01.10 |
Hooks 규칙 (0) | 2024.01.04 |
[React] 카카오맵 지도 라이브러리 사용방법 (1) | 2023.12.20 |
[React] 캐로셀 직접 구현하기 (0) | 2023.12.15 |