如何在 Material-UI 中使用 Box 组件覆盖按钮?

Posted

技术标签:

【中文标题】如何在 Material-UI 中使用 Box 组件覆盖按钮?【英文标题】:How to use override Button using Box component in Material-UI? 【发布时间】:2020-07-13 04:03:19 【问题描述】:

我一直在尝试在 Material-UI 中的 Box 组件上理解和编写代码。 (https://material-ui.com/components/box/#box)

我一直在尝试以文档中描述的两种方式覆盖 Button 组件,但我不知道如何。当我使用这两种方法运行代码段时,按钮出现但没有颜色变化。然后,当我尝试在克隆元素代码段下方添加一个额外的按钮时,我收到一条错误消息,提示“无法读取未定义的属性 'className'”。

            <Box color="primary" clone>
                <Button>Click</Button>
                <Button>Click</Button>
            </Box>

当我以第二种渲染道具的方式在下面添加一个 Button 组件时,第一个按钮完全从 DOM 中消失。


             <Box color="secondary">
                props => <Button ...props > Click </Button>
                <Button color="secondary">Click</Button>
            </Box> 

希望能解释一下覆盖底层 DOM 元素的工作原理。

【问题讨论】:

这能回答你的问题吗? ***.com/a/60926017/11872246 很遗憾没有。我确实想覆盖样式,但只能使用 Box 组件文档中提到的任何一种方法。使用克隆元素或渲染道具。 【参考方案1】:

您在问题中显示的代码存在一些问题。

    primarysecondary 不是调色板中的有效颜色。它们是Buttoncolor 属性的有效选项,但在这里您尝试在主题的palette 对象中引用颜色。为此,您需要primary.mainsecondary.main(当您指定&lt;Button color="primary"&gt; 时,这就是Button uses)。

    Box 在使用 clone 属性时仅支持单个子元素,而在使用渲染道具方法时仅支持单个子元素。在您的两个示例中,您都有两个孩子。


这是处理克隆选项的Material-UI source code:

      if (clone) 
        return React.cloneElement(children, 
          className: clsx(children.props.className, className),
          ...spread,
        );
      

这是创建一个新的子元素,它将Box 生成的className 与子元素上的任何现有类名组合在一起。它通过children.props.className 获取这个现有的类名,但是当有多个子级时,children 将是一个元素数组,并且没有props 属性,因此您会收到错误消息:

无法读取未定义的属性“className”


这是处理渲染道具方法的Material-UI source code:

      if (typeof children === 'function') 
        return children( className, ...spread );
      

当您有多个孩子时,typeof children === 'function' 将不正确,并且不会使用渲染道具方法。在这种情况下,两个孩子都只是得到正常的反应渲染,而尝试渲染一个函数不会渲染任何东西。


下面是一个工作示例,它通过在 clone 案例中使用单个 Button 子级和在渲染道具案例中使用单个函数子级(然后渲染两个 Button 元素的函数)来解决所有这些问题.

import React from "react";
import Button from "@material-ui/core/Button";
import Box from "@material-ui/core/Box";

export default function App() 
  return (
    <>
      <Box color="primary.main" clone>
        <Button>Click</Button>
      </Box>
      <Box color="secondary.main">
        props => (
          <>
            <Button ...props> Click </Button>
            <Button color="secondary">Click</Button>
          </>
        )
      </Box>
    </>
  );

【讨论】:

惊人的解释!非常感谢。 所以我只是在我的 React 项目中更改了我的代码以匹配您的代码,并且按钮的颜色仍然没有改变。我截图了。 imgur.com/a/4EY6upk 导入的顺序很重要。你在 Button 之前有 Box,但我在之后有它。导入顺序会影响&lt;head&gt; 中生成样式的顺序,因此当特异性相同时哪些样式会胜出。不幸的是,重要的顺序是它们首先导入的顺序,因此即使在导入Button 之前使用的其他页面中导入Box 也有可能造成混乱这个了。 您可以在我的回答中找到有关此导入顺序效果的更多说明:***.com/questions/56929702/… 修复了它。非常感谢。

以上是关于如何在 Material-UI 中使用 Box 组件覆盖按钮?的主要内容,如果未能解决你的问题,请参考以下文章

ReactJS + Material-UI:如何在每个 TableRow 中使用 Material-UI 的 FlatButton 和 Dialog?

如何在 Material-UI 菜单中使用自定义功能组件

Material-UI 中使用 Styled-Components 的媒体查询

Material-ui卡片翻转动画

如何在 asp.net mvc 项目中使用 Material-UI

如何在 React 测试库中获取 Material-UI 密码输入