하단 네비게이션

하단 네비게이션 (Bottom Navigation)

하단 네비게이션 바는 앱의 주요 목적지(destination) 사이를 이동할 수 있게 해줘요. 하단 네비게이션 바는 화면 하단에 3~5개의 목적지를 표시해요. 각 목적지는 아이콘과 선택적인 텍스트 레이블로 표현되고, 하단 네비게이션 아이콘을 누르면 해당 아이콘과 연결된 최상위 네비게이션 목적지로 이동해요.

출처: 문서

본문

하단 네비게이션 (Bottom navigation)

액션이 세 개뿐일 때는 아이콘과 텍스트 레이블을 항상 함께 표시해요.

import * as React from 'react';
import Box from '@mui/material/Box';
import BottomNavigation from '@mui/material/BottomNavigation';
import BottomNavigationAction from '@mui/material/BottomNavigationAction';
import RestoreIcon from '@mui/icons-material/Restore';
import FavoriteIcon from '@mui/icons-material/Favorite';
import LocationOnIcon from '@mui/icons-material/LocationOn';

export default function SimpleBottomNavigation() {
  const [value, setValue] = React.useState(0);

  return (
    <Box sx={{ width: 500 }}>
      <BottomNavigation
        showLabels
        value={value}
        onChange={(event, newValue) => {
          setValue(newValue);
        }}
      >
        <BottomNavigationAction label="Recents" icon={<RestoreIcon />} />
        <BottomNavigationAction label="Favorites" icon={<FavoriteIcon />} />
        <BottomNavigationAction label="Nearby" icon={<LocationOnIcon />} />
      </BottomNavigation>
    </Box>
  );
}

레이블 없는 하단 네비게이션 (Bottom navigation with no label)

액션이 네 개 또는 다섯 개라면, 비활성 상태의 뷰는 아이콘으로만 표시해요.

import * as React from 'react';
import BottomNavigation from '@mui/material/BottomNavigation';
import BottomNavigationAction from '@mui/material/BottomNavigationAction';
import FolderIcon from '@mui/icons-material/Folder';
import RestoreIcon from '@mui/icons-material/Restore';
import FavoriteIcon from '@mui/icons-material/Favorite';
import LocationOnIcon from '@mui/icons-material/LocationOn';

export default function LabelBottomNavigation() {
  const [value, setValue] = React.useState('recents');

  const handleChange = (event: React.SyntheticEvent, newValue: string) => {
    setValue(newValue);
  };

  return (
    <BottomNavigation sx={{ width: 500 }} value={value} onChange={handleChange}>
      <BottomNavigationAction
        label="Recents"
        value="recents"
        icon={<RestoreIcon />}
      />
      <BottomNavigationAction
        label="Favorites"
        value="favorites"
        icon={<FavoriteIcon />}
      />
      <BottomNavigationAction
        label="Nearby"
        value="nearby"
        icon={<LocationOnIcon />}
      />
      <BottomNavigationAction label="Folder" value="folder" icon={<FolderIcon />} />
    </BottomNavigation>
  );
}

고정 위치 (Fixed positioning)

이 데모는 화면에 콘텐츠가 얼마나 있든 상관없이 하단 네비게이션을 화면 하단에 고정해두는 방법을 보여줘요.

import * as React from 'react';
import Box from '@mui/material/Box';
import CssBaseline from '@mui/material/CssBaseline';
import BottomNavigation from '@mui/material/BottomNavigation';
import BottomNavigationAction from '@mui/material/BottomNavigationAction';
import RestoreIcon from '@mui/icons-material/Restore';
import FavoriteIcon from '@mui/icons-material/Favorite';
import ArchiveIcon from '@mui/icons-material/Archive';
import Paper from '@mui/material/Paper';
import List from '@mui/material/List';
import ListItemButton from '@mui/material/ListItemButton';
import ListItemAvatar from '@mui/material/ListItemAvatar';
import ListItemText from '@mui/material/ListItemText';
import Avatar from '@mui/material/Avatar';

function refreshMessages(): MessageExample[] {
  const getRandomInt = (max: number) => Math.floor(Math.random() * Math.floor(max));

  return Array.from(new Array(50)).map(
    () => messageExamples[getRandomInt(messageExamples.length)],
  );
}

export default function FixedBottomNavigation() {
  const [value, setValue] = React.useState(0);
  const ref = React.useRef<HTMLDivElement>(null);
  const [messages, setMessages] = React.useState(() => refreshMessages());

  React.useEffect(() => {
    (ref.current as HTMLDivElement).ownerDocument.body.scrollTop = 0;
    setMessages(refreshMessages());
  }, [value, setMessages]);

  return (
    <Box sx={{ pb: 7 }} ref={ref}>
      <CssBaseline />
      <List>
        {messages.map(({ primary, secondary, person }, index) => (
          <ListItemButton key={index + person}>
            <ListItemAvatar>
              <Avatar alt="Profile Picture" src={person} />
            </ListItemAvatar>
            <ListItemText primary={primary} secondary={secondary} />
          </ListItemButton>
        ))}
      </List>
      <Paper sx={{ position: 'fixed', bottom: 0, left: 0, right: 0 }} elevation={3}>
        <BottomNavigation
          showLabels
          value={value}
          onChange={(event, newValue) => {
            setValue(newValue);
          }}
        >
          <BottomNavigationAction label="Recents" icon={<RestoreIcon />} />
          <BottomNavigationAction label="Favorites" icon={<FavoriteIcon />} />
          <BottomNavigationAction label="Archive" icon={<ArchiveIcon />} />
        </BottomNavigation>
      </Paper>
    </Box>
  );
}

interface MessageExample {
  primary: string;
  secondary: string;
  person: string;
}

const messageExamples: readonly MessageExample[] = [
  {
    primary: 'Brunch this week?',
    secondary: "I'll be in the neighbourhood this week. Let's grab a bite to eat",
    person: '/static/images/avatar/5.jpg',
  },
  {
    primary: 'Birthday Gift',
    secondary: `Do you have a suggestion for a good present for John on his work
      anniversary. I am really confused & would love your thoughts on it.`,
    person: '/static/images/avatar/1.jpg',
  },
  {
    primary: 'Recipe to try',
    secondary: 'I am try out this new BBQ recipe, I think this might be amazing',
    person: '/static/images/avatar/2.jpg',
  },
  {
    primary: 'Yes!',
    secondary: 'I have the tickets to the ReactConf for this year.',
    person: '/static/images/avatar/3.jpg',
  },
  {
    primary: "Doctor's Appointment",
    secondary: 'My appointment for the doctor was rescheduled for next Saturday.',
    person: '/static/images/avatar/4.jpg',
  },
  {
    primary: 'Discussion',
    secondary: `Menus that are generated by the bottom app bar (such as a bottom
      navigation drawer or overflow menu) open as bottom sheets at a higher elevation
      than the bar.`,
    person: '/static/images/avatar/5.jpg',
  },
  {
    primary: 'Summer BBQ',
    secondary: `Who wants to have a cookout this weekend? I just got some furniture
      for my backyard and would love to fire up the grill.`,
    person: '/static/images/avatar/1.jpg',
  },
];

서드파티 라우팅 라이브러리 (Third-party routing library)

흔한 사용 사례 중 하나는 서버로 HTTP 왕복(round-trip)하지 않고 클라이언트에서만 네비게이션을 수행하는 것이에요. BottomNavigationAction 컴포넌트는 이 사용 사례를 처리하기 위해 component prop을 제공해요. 더 자세한 내용은 이 가이드를 참고하세요.

BottomNavigation API

데모 (Demos)

이 React 컴포넌트의 사용 예시와 세부 사항은 컴포넌트 데모 페이지를 방문해보세요:

임포트 (Import)

import BottomNavigation from '@mui/material/BottomNavigation';
// or
import { BottomNavigation } from '@mui/material';

Props

Name Type Default Required Description
children node - No
classes object - No Override or extend the styles applied to the component.
component elementType - No
onChange function(event: React.SyntheticEvent, value: any) => void - No
showLabels bool false No
sx Array<func | object | bool> | func | object - No The system prop that allows defining system overrides as well as additional CSS styles.
value any - No

Note: The ref is forwarded to the root element (HTMLDivElement).

Any other props supplied will be provided to the root element (native element).

테마 기본 props (Theme default props)

MuiBottomNavigation를 사용하면 테마로 이 컴포넌트의 기본 props를 바꿀 수 있어요.

CSS 규칙 이름 (Rule name)

Global class Rule name Description
- root Styles applied to the root element.

소스 코드 (Source code)

이 페이지에서 원하는 정보를 찾지 못했다면, 더 자세한 내용을 위해 컴포넌트의 구현을 살펴보는 것을 고려해보세요.

BottomNavigationAction API

데모 (Demos)

임포트 (Import)

import BottomNavigationAction from '@mui/material/BottomNavigationAction';
// or
import { BottomNavigationAction } from '@mui/material';

Props

Name Type Default Required Description
children unsupportedProp - No
classes object - No Override or extend the styles applied to the component.
icon node - No
label node - No
showLabel bool - No
slotProps { label?: func | object, root?: func | object } {} No
slots { label?: elementType, root?: elementType } {} No
sx Array<func | object | bool> | func | object - No The system prop that allows defining system overrides as well as additional CSS styles.
value any - No

Note: The ref is forwarded to the root element (HTMLButtonElement).

Any other props supplied will be provided to the root element (ButtonBase).

상속 (Inheritance)

명시적으로 문서화되진 않았지만, ButtonBase 컴포넌트의 props도 BottomNavigationAction에서 사용할 수 있어요.

테마 기본 props (Theme default props)

MuiBottomNavigationAction를 사용하면 테마로 이 컴포넌트의 기본 props를 바꿀 수 있어요.

슬롯 (Slots)

Name Default Class Description
root ButtonBase .MuiBottomNavigationAction-root The component that renders the root.
label span .MuiBottomNavigationAction-label The component that renders the label.

CSS 규칙 이름 (Rule name)

Global class Rule name Description
- iconOnly State class applied to the root element if showLabel={false} and not selected.
.Mui-selected - State class applied to the root element if selected.

소스 코드 (Source code)

더 알아보기 (Learn more)