React MUI 앱바(AppBar)와 드로워(Drawer)에서 발생하는 로고 아이콘 클릭 오류

송연지·2024년 8월 27일
0

트러블슈팅

목록 보기
10/32

React MUI 앱바(AppBar)와 드로워(Drawer)에서 발생하는 로고 아이콘 클릭 문제 해결하기

소개

리액트(React)와 MUI(Material-UI)를 사용하여 웹 애플리케이션을 개발할 때, AppBarDrawer를 자주 사용하게 됩니다. 이 둘을 함께 사용할 때, 특히 로고나 아이콘AppBarDrawer에 각각 배치하는 경우, z-index 문제로 인해 로고가 클릭되지 않거나 드로워의 로고가 앱바의 로고 위에 겹치는 문제가 발생할 수 있습니다. 이 글에서는 이러한 문제를 어떻게 해결할 수 있는지에 대해 자세히 설명하겠습니다.

문제 상황

기본적으로 MUI의 AppBarDrawer는 서로 다른 z-index를 가지며, 특정 조건에서 AppBarDrawer의 로고가 클릭되지 않는 문제가 발생할 수 있습니다. 이는 주로 Drawerz-indexAppBarz-index보다 높거나, 두 컴포넌트의 로고 위치가 겹치는 경우에 발생합니다.

아래는 문제가 발생할 수 있는 기본적인 구조입니다.

import React, { useState } from 'react';
import { AppBar, Toolbar, IconButton, Drawer, List, ListItem, ListItemText } from '@mui/material';
import MenuIcon from '@mui/icons-material/Menu';
import AppBarLogo from './AppBarLogo';  // 앱바의 로고
import DrawerLogo from './DrawerLogo';  // 드로워의 로고

const MyApp = () => {
  const [drawerOpen, setDrawerOpen] = useState(false);

  const toggleDrawer = (open) => (event) => {
    if (event.type === 'keydown' && (event.key === 'Tab' || event.key === 'Shift')) {
      return;
    }
    setDrawerOpen(open);
  };

  return (
    <div>
      <AppBar position="fixed">
        <Toolbar>
          <AppBarLogo />
          <IconButton edge="start" color="inherit" aria-label="menu" onClick={toggleDrawer(true)}>
            <MenuIcon />
          </IconButton>
        </Toolbar>
      </AppBar>
      <Drawer anchor="left" open={drawerOpen} onClose={toggleDrawer(false)}>
        <DrawerLogo />
        <List>
          <ListItem button>
            <ListItemText primary="Item 1" />
          </ListItem>
          <ListItem button>
            <ListItemText primary="Item 2" />
          </ListItem>
        </List>
      </Drawer>
    </div>
  );
};

export default MyApp;

위의 코드에서는 AppBar와 Drawer 각각에 로고를 배치했습니다. 그러나 Drawer가 열릴 때 z-index 문제로 인해 AppBar의 로고가 클릭되지 않거나, 드로워의 로고가 앱바의 로고 위에 겹쳐서 나타날 수 있습니다.

문제 원인

MUI의 Drawer 컴포넌트는 기본적으로 높은 z-index 값을 가지며, 이는 AppBar 위에 그려지기 때문에 발생하는 문제입니다. 특히, 앱바와 드로워에 각각 다른 로고를 배치한 경우, 드로워의 로고가 앱바의 로고를 가리거나, 앱바의 로고가 클릭되지 않게 됩니다.

해결 방법

  1. AppBar의 z-index 조정
    가장 간단한 해결 방법은 AppBar의 z-index를 Drawer보다 높게 설정하는 것입니다. 이를 통해 Drawer가 열려 있을 때도 AppBar의 로고가 정상적으로 클릭될 수 있습니다.
import React, { useState } from 'react';
import { AppBar, Toolbar, IconButton, Drawer, List, ListItem, ListItemText } from '@mui/material';
import MenuIcon from '@mui/icons-material/Menu';
import AppBarLogo from './AppBarLogo';
import DrawerLogo from './DrawerLogo';
import { styled } from '@mui/material/styles';

const StyledAppBar = styled(AppBar)(({ theme }) => ({
  zIndex: theme.zIndex.drawer + 1, // z-index를 Drawer보다 높게 설정
}));

const MyApp = () => {
  const [drawerOpen, setDrawerOpen] = useState(false);

  const toggleDrawer = (open) => (event) => {
    if (event.type === 'keydown' && (event.key === 'Tab' || event.key === 'Shift')) {
      return;
    }
    setDrawerOpen(open);
  };

  return (
    <div>
      <StyledAppBar position="fixed">
        <Toolbar>
          <AppBarLogo />
          <IconButton edge="start" color="inherit" aria-label="menu" onClick={toggleDrawer(true)}>
            <MenuIcon />
          </IconButton>
        </Toolbar>
      </StyledAppBar>
      <Drawer anchor="left" open={drawerOpen} onClose={toggleDrawer(false)}>
        <DrawerLogo />
        <List>
          <ListItem button>
            <ListItemText primary="Item 1" />
          </ListItem>
          <ListItem button>
            <ListItemText primary="Item 2" />
          </ListItem>
        </List>
      </Drawer>
    </div>
  );
};

export default MyApp;

위 코드에서 StyledAppBar를 사용하여 AppBar의 z-index를 Drawer보다 높게 설정했습니다. 이로 인해 드로워가 열려 있을 때도 AppBar의 로고가 드로워의 로고보다 위에 위치하게 되고, 클릭이 가능해집니다.

  1. Drawer의 Backdrop 설정 조정
    또 다른 방법은 Drawer의 Backdrop 속성을 조정하여 AppBar의 로고가 항상 상단에 위치하도록 하는 것입니다. 이 경우, Drawer가 열려 있을 때도 AppBar의 로고가 정상적으로 동작하게 됩니다.
import React, { useState } from 'react';
import { AppBar, Toolbar, IconButton, Drawer, List, ListItem, ListItemText } from '@mui/material';
import MenuIcon from '@mui/icons-material/Menu';
import AppBarLogo from './AppBarLogo';
import DrawerLogo from './DrawerLogo';

const MyApp = () => {
  const [drawerOpen, setDrawerOpen] = useState(false);

  const toggleDrawer = (open) => (event) => {
    if (event.type === 'keydown' && (event.key === 'Tab' || event.key === 'Shift')) {
      return;
    }
    setDrawerOpen(open);
  };

  return (
    <div>
      <AppBar position="fixed" sx={{ zIndex: (theme) => theme.zIndex.drawer + 1 }}>
        <Toolbar>
          <AppBarLogo />
          <IconButton edge="start" color="inherit" aria-label="menu" onClick={toggleDrawer(true)}>
            <MenuIcon />
          </IconButton>
        </Toolbar>
      </AppBar>
      <Drawer
        anchor="left"
        open={drawerOpen}
        onClose={toggleDrawer(false)}
        BackdropProps={{ invisible: true }} // Backdrop을 비활성화하여 Drawer가 열려도 AppBar가 상단에 위치
      >
        <DrawerLogo />
        <List>
          <ListItem button>
            <ListItemText primary="Item 1" />
          </ListItem>
          <ListItem button>
            <ListItemText primary="Item 2" />
          </ListItem>
        </List>
      </Drawer>
    </div>
  );
};

export default MyApp;

여기서는 BackdropProps의 invisible 속성을 true로 설정하여 Drawer의 백드롭(배경)을 비활성화했습니다. 이로 인해 AppBar가 항상 상단에 위치하게 되어, 앱바와 드로워의 로고가 겹치지 않으며, AppBar의 로고가 클릭 가능한 상태가 유지됩니다.

결론

리액트와 MUI를 사용하여 AppBar와 Drawer를 함께 사용할 때, z-index 문제로 인해 발생할 수 있는 로고 아이콘 클릭 문제를 해결하는 방법에 대해 알아보았습니다. AppBar의 z-index를 조정하거나, Drawer의 Backdrop 설정을 조정하는 방식으로 이 문제를 해결할 수 있습니다. 이 방법을 통해 더욱 직관적이고 사용자 친화적인 UI를 구현할 수 있기를 바랍니다.

profile
프론트엔드 개발쟈!!

0개의 댓글