본문 바로가기
IT 톺아보기/기술 공부

[React][Typescript] Dialog 기능 이용할 때 깜빡임 발생 해결

by 파초우 2023. 6. 25.
반응형

목차

  1. 개요
  2. 문제점
  3. 해결법

개요

이메일 회원가입 기능을 개발하면서 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

 

A Look at React Hooks: useRef vs useState

Let's learn about the differences between useRef vs useState and uncontrolled vs controlled components!

lo-victoria.com

반응형