You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React抽离组件属性样式遇TS错误,求解决方案

解决IconButton属性抽离的TypeScript错误及实现方案

问题根源

你遇到的Cannot redeclare block-scoped variable '(Missing)'错误,核心原因是iconButtonOptions里的sx属性写成了双层大括号,属于语法错误:

// 错误写法
sx: {{ mr: 2, ...(open && { display: "none" }) }}
// 正确写法:sx的值本身就是样式对象,只需单层大括号
sx: { mr: 2, ...(open && { display: "none" }) }

修正后的完整代码

先修复语法错误,同时建议替换any类型,给组件Props定义明确的TypeScript类型,让代码更严谨:

import { AppBar, Toolbar, IconButton, Box, Typography, useTheme } from '@mui/material';
import MenuIcon from '@mui/icons-material/Menu';

// 定义AppBar组件的Props类型
type AppBarProps = {
  open: boolean;
  onDrawerOpen: () => void;
};

export default function AppBarComponent({ open, onDrawerOpen }: AppBarProps) {
  const theme = useTheme();
  const iconButtonOptions = {
    color: "inherit" as const,
    ariaLabel: "open drawer",
    onClick: onDrawerOpen,
    edge: "start" as const,
    sx: { mr: 2, ...(open && { display: "none" }) }
  };

  return (
    <AppBar position="fixed" style={{ background: "#002a5e" }} open={open}>
      <Toolbar>
        <Box sx={{ display: "flex", flexDirection: "row", alignItems: "center", flex: "1" }}>
          <IconButton {...iconButtonOptions}>
            <MenuIcon />
          </IconButton>
          <Typography variant="h6" noWrap component="div">
            TITLE
          </Typography>
        </Box>
        <Box
          component="img"
          sx={{ height: 32 }}
          alt="MyLogo"
          src={logo} // 确保logo已正确导入
        />
        <Box sx={{ flex: "1" }}></Box>
      </Toolbar>
    </AppBar>
  );
}

进阶:抽离为自定义组件(更适合复用)

如果需要在多个地方复用这个配置的IconButton,直接封装成自定义组件比常量更灵活:

import { IconButton, IconButtonProps } from '@mui/material';
import MenuIcon from '@mui/icons-material/Menu';

type DrawerToggleButtonProps = Pick<IconButtonProps, 'onClick'> & {
  open: boolean;
};

export const DrawerToggleButton = ({ onClick, open }: DrawerToggleButtonProps) => {
  return (
    <IconButton
      color="inherit"
      aria-label="open drawer"
      onClick={onClick}
      edge="start"
      sx={{ mr: 2, ...(open && { display: "none" }) }}
    >
      <MenuIcon />
    </IconButton>
  );
};

在AppBar中直接使用该组件:

// 导入自定义组件
import { DrawerToggleButton } from './DrawerToggleButton';

export default function AppBarComponent({ open, onDrawerOpen }: AppBarProps) {
  return (
    <AppBar position="fixed" style={{ background: "#002a5e" }} open={open}>
      <Toolbar>
        <Box sx={{ display: "flex", flexDirection: "row", alignItems: "center", flex: "1" }}>
          <DrawerToggleButton onClick={onDrawerOpen} open={open} />
          <Typography variant="h6" noWrap component="div">
            TITLE
          </Typography>
        </Box>
        {/* ...其他内容 */}
      </Toolbar>
    </AppBar>
  );
}

内容的提问来源于stack exchange,提问作者Sandeep Thomas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 00:35:20