【问题标题】:Share values and events across different components in React在 React 中的不同组件之间共享值和事件
【发布时间】:2022-12-15 12:03:22
【问题描述】:

我正在尝试基于此演示构建一个带有基本 AppBar 和抽屉的仪表板应用程序

https://codesandbox.io/s/nj3u0q?file=/demo.tsx

但在这个 Demo 中,AppBar 和 Drawer 以及 Main 内容都在一个页面中。

但我把它做成单独的组件并做了这样的布局

RootContainer.tsx

import * as React from 'react';
import { styled, useTheme } from '@mui/material/styles';
import Box from '@mui/material/Box';
import CssBaseline from '@mui/material/CssBaseline';
import MuiAppBar, { AppBarProps as MuiAppBarProps } from '@mui/material/AppBar';
import Drawer from './Drawer';
import AppBar from './AppBar';
import Main from './MainContent';

export default function PersistentDrawerLeft() {
  const [open, setOpen] = React.useState(false);

  return (
    <Box sx={{ display: 'flex' }}>
      <CssBaseline />
      <AppBar />
      <Drawer />
      <Main />
      
    </Box>
  );
}

应用栏.tsx

import * as React from 'react';
import { styled, useTheme } from '@mui/material/styles';

import MuiAppBar, { AppBarProps as MuiAppBarProps } from '@mui/material/AppBar';
import Toolbar from '@mui/material/Toolbar';
import Typography from '@mui/material/Typography';
import IconButton from '@mui/material/IconButton';
import MenuIcon from '@mui/icons-material/Menu';      
const drawerWidth = 240;        
interface AppBarProps extends MuiAppBarProps {
  open?: boolean;
}

const AppBar = styled(MuiAppBar, {
  shouldForwardProp: (prop) => prop !== 'open',
})<AppBarProps>(({ theme, open }) => ({
  transition: theme.transitions.create(['margin', 'width'], {
    easing: theme.transitions.easing.sharp,
    duration: theme.transitions.duration.leavingScreen,
  }),
  ...(open && {
    width: `calc(100% - ${drawerWidth}px)`,
    marginLeft: `${drawerWidth}px`,
    transition: theme.transitions.create(['margin', 'width'], {
      easing: theme.transitions.easing.easeOut,
      duration: theme.transitions.duration.enteringScreen,
    }),
  }),
})); 


export default function AppBar() {
  const theme = useTheme();
  const [open, setOpen] = React.useState(false);

  const handleDrawerOpen = () => {
    setOpen(true);
  };       

  return (
      <AppBar position="fixed" style={{background:'#002a5e'}} open={open}>
        <Toolbar>
          <IconButton
            color="inherit"
            aria-label="open drawer"
            onClick={handleDrawerOpen}
            edge="start"
            sx={{ mr: 2, ...(open && { display: 'none' }) }}
          >
            <MenuIcon />
          </IconButton>
          <Typography variant="h6" noWrap component="div">
            Test
          </Typography>
          
        </Toolbar>
      </AppBar>
  );
}

但问题是当我点击应用栏上的三明治按钮时,它会减小宽度以显示抽屉,但抽屉根本不显示。

抽屉.tsx

import * as React from "react";
import { styled, useTheme } from "@mui/material/styles";
import Drawer from "@mui/material/Drawer";
import List from "@mui/material/List";
import Divider from "@mui/material/Divider";
import IconButton from "@mui/material/IconButton";
import ChevronLeftIcon from "@mui/icons-material/ChevronLeft";
import ChevronRightIcon from "@mui/icons-material/ChevronRight";
import ListItem from "@mui/material/ListItem";
import ListItemButton from "@mui/material/ListItemButton";
import ListItemIcon from "@mui/material/ListItemIcon";
import ListItemText from "@mui/material/ListItemText";
import InboxIcon from "@mui/icons-material/MoveToInbox";
import MailIcon from "@mui/icons-material/Mail";

const drawerWidth = 240;

const DrawerHeader = styled("div")(({ theme }) => ({
  display: "flex",
  alignItems: "center",
  padding: theme.spacing(0, 1),
  // necessary for content to be below app bar
  ...theme.mixins.toolbar,
  justifyContent: "flex-end",
}));

export default function Drawer() {
  const theme = useTheme();
  const [open, setOpen] = React.useState(false);

  const handleDrawerOpen = () => {
    setOpen(true);
  };

  const handleDrawerClose = () => {
    setOpen(false);
  };

  return (
    <Drawer
      sx={{
        width: drawerWidth,
        flexShrink: 0,
        "& .MuiDrawer-paper": {
          width: drawerWidth,
          boxSizing: "border-box",
        },
      }}
      variant="persistent"
      anchor="left"
      open={open}
    >
      <DrawerHeader>
        <IconButton onClick={handleDrawerClose}>
          {theme.direction === "ltr" ? (
            <ChevronLeftIcon />
          ) : (
            <ChevronRightIcon />
          )}
        </IconButton>
      </DrawerHeader>
      <Divider />
      <List>
        {["Manage Recipe", "Reports", "Settings"].map((text, index) => (
          <ListItem key={text} disablePadding>
            <ListItemButton>
              <ListItemIcon>
                {index % 2 === 0 ? <InboxIcon /> : <MailIcon />}
              </ListItemIcon>
              <ListItemText primary={text} />
            </ListItemButton>
          </ListItem>
        ))}
      </List>
    </Drawer>
  );
}

我猜这个问题是因为开放常量没有更新到抽屉组件中。我很新,或者只有几天的反应经验。请帮助如何将应用栏中的这些点击事件和常量共享到抽屉

【问题讨论】:

  • 您可以与您的代码共享一个沙箱吗?

标签: reactjs typescript material-ui


【解决方案1】:

看起来分离后,每个组件都有自己的 open 状态和处理函数,因此不共享行为。

RootContainer中似乎已经有一个open状态,尝试将状态和处理函数作为道具传递给组件:

export default function PersistentDrawerLeft() {
  const [open, setOpen] = React.useState(false);

  const handleDrawerOpen = () => {
    setOpen(true);
  };

  const handleDrawerClose = () => {
    setOpen(false);
  };

  return (
    <Box sx={{ display: "flex" }}>
      <CssBaseline />
      <AppBar open={open} onDrawerOpen={handleDrawerOpen} />
      <Drawer open={open} onDrawerClose={handleDrawerClose} />
      <Main />
    </Box>
  );
}

让每个组件使用 props 中的 open 状态和处理程序,而不是它们自己的:

export default function AppBar({ open, onDrawerOpen }) {
  const theme = useTheme();

  return (
    <AppBar position="fixed" style={{ background: "#002a5e" }} open={open}>
      <Toolbar>
        <IconButton
          color="inherit"
          aria-label="open drawer"
          onClick={onDrawerOpen}
          edge="start"
          sx={{ mr: 2, ...(open && { display: "none" }) }}
        >
          <MenuIcon />
        </IconButton>
        <Typography variant="h6" noWrap component="div">
          Test
        </Typography>
      </Toolbar>
    </AppBar>
  );
}

【讨论】:

    猜你喜欢
    • 2016-03-22
    • 1970-01-01
    • 2020-11-08
    • 2019-01-31
    • 1970-01-01
    • 1970-01-01
    • 2016-10-23
    • 2019-05-16
    • 2015-08-25
    相关资源
    最近更新 更多