목차
개요
이메일 회원가입 기능을 개발하면서 dialog를 이용하려다 보니 문제점이 하나 발생했다.
바로 한 글자를 칠 때 마다 깜박임이 발생하는 것이다.
혼자 해결하려고 했으나, 잘 되지 않아 커뮤니티에 질문을 하며 문제를 해결해나갔다.
문제점
Dialog 기능에서 email과 password를 useState를 통해 값을 받으니 자동으로 리렌더링이 발생하는 문제가 있었다.
코드는 아래와 같이 작성했다.
import * as React from 'react';
import { useState } from 'react';
import {
AppBar,
Box,
Button,
Dialog,
DialogActions,
DialogContent,
DialogTitle,
IconButton,
Menu,
MenuItem,
Stack,
TextField,
} from '@mui/material';
import { NotificationsOutlined, Person3Outlined, SearchOutlined } from '@mui/icons-material';
import { GoogleLogin, GithubLogin, EmailSignUp } from './FirebaseLogin';
import colorConfig from '../../configs/colorConfig';
const HeaderLayout = () => {
const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);
const [open, setOpen] = useState(false);
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
...
const emailChange = ({ target: { value } }) => setEmail(value);
const passwordChange = (e: any) => {
setPassword(e.currentTarget.value);
};
const onSubmit = (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
EmailSignUp(email, password);
};
const AlertDialog = () => {
return (
<Dialog
open={open}
onClose={handleClose}
aria-labelledby="alert-dialog-title"
aria-describedby="alert-dialog-description"
>
<DialogTitle id="alert-dialog-title">{'Use Google'}</DialogTitle>
<Box component="form" onSubmit={onSubmit}>
<DialogContent>
<div>
<TextField id="email" type="email" value={email} onChange={emailChange} placeholder="Email" />
<div />
<TextField
id="password"
type="password"
value={password}
onChange={passwordChange}
placeholder="Password"
/>
</div>
</DialogContent>
<DialogActions>
<Button type="submit" onClick={closeAlert}>
회원가입
</Button>
</DialogActions>
</Box>
</Dialog>
);
};
...
};
export default HeaderLayout;
onChange 부분에서 값이 변할 때마다 리렌더링이 진행이 되었고 그 이후에는 계속 TextField를 클릭해야 입력해야하는 불편함이 생겼다.
해결법
Controlled component가 아닌 Uncontrolled component를 이용하면 문제가 해결되는 것을 볼 수 있다.
useRef를 이용하여 값을 저장하고 이를 submit하는 방식으로 error 해결했다.
import React, { useRef } from 'react';
import {
Dialog,
DialogTitle,
DialogContent,
Button,
} from '@mui/material';
interface AlertDialogProps {
open: boolean;
handleClose: () => void;
onSubmit: (event: React.FormEvent<HTMLFormElement>) => void;
}
const AlertDialog: React.FC<AlertDialogProps> = ({ open, handleClose, onSubmit }) => {
const email = useRef<HTMLInputElement>(null);
const password = useRef<HTMLInputElement>(null);
return (
<Dialog
open={open}
onClose={handleClose}
aria-labelledby="alert-dialog-title"
aria-describedby="alert-dialog-description"
>
<DialogTitle id="alert-dialog-title">{'Use Google'}</DialogTitle>
<DialogContent>
<form onSubmit={onSubmit}>
<div>
<input id="email" type="email" ref={email} placeholder="Email" />
<div />
<input id="password" type="password" ref={password} placeholder="Password" />
</div>
<Button type="submit" onClick={handleClose}>
회원가입
</Button>
</form>
</DialogContent>
</Dialog>
);
};
export default AlertDialog;
useRef를 사용하여 값을 저장하는데 있어 리렌더링을 방지하고 Textfield tag에서 input tag로 변경해주었다. Tag 변경은 ref라는 요소를 사용하기 위함이고
onSubmit에서 우리가 작성한 값을 전달할때에는 HTMLInputElement 형태로 전달할 수 없기 때문에 EmailSignUp(email.current?.value as string, password.current?.value as string);
방식으로 작성하여 string type으로 값을 전달 했다.
이후에 firebase에 들어가면 잘 들어가있는 것을 볼 수 있다.
출처
https://lo-victoria.com/a-look-at-react-hooks-useref-vs-usestate
'IT 톺아보기 > 기술 공부' 카테고리의 다른 글
[Window] 사내망 등의 이유로 yarn 설치가 안되는 경우 (1) | 2023.06.16 |
---|---|
[React][Typescript] Firebase console을 이용한 Login 기능 구현 (0) | 2023.06.16 |
Matlab Simulink hasChangedTo Local Parameter Error 해결법 (0) | 2023.06.01 |
Vue 공부 - 1 (2) | 2023.03.13 |
작심삼일 JavaScript 정리 - 1 (0) | 2023.03.02 |