초보 개발자의 성장 일기
로그인 입력폼이 유효하지 않을 때 본문
로그인 폼을 구현하다가 사용자가 로그인할 때 입력폼에 아무것도 입력되지 않으면
- 로그인 버튼을 비활성화를 해야할지
- 입력 폼에 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 | 
 
                  