【问题标题】:How to change button props based on breakpoints in Material UI如何根据 Material UI 中的断点更改按钮道具
【发布时间】:2019-02-27 13:14:10
【问题描述】:

我正在尝试针对不同的屏幕尺寸更改 Material-ui 按钮上的变体和/或尺寸。例如,在“sm”断点下方不使用变体或 size="small",在“sm”上方使用 variant="outlined" 和/或 size="large"。

通常,我会使用 withStyles 并使用 theme.breakpoints 创建一个样式,以通过使用 className 将样式应用于元素来影响更改,但是,variant 和 size 是道具。

在阅读the api、搜索网络和大量摆弄之后,我似乎无法找到任何直接的方法来根据视口宽度更改道具。

我考虑过创建一个“宽度检测器”,然后使用一些 JS 逻辑来相应地更改按钮元素的道具,但这似乎只是一个有点遥远的解决方案。

所以我在这里询问是否有更简单的解决方案。谢谢。

【问题讨论】:

    标签: reactjs material-ui


    【解决方案1】:

    withWidth HOC 已被 Material UI Docs 弃用。

    这是现在有效的方法,结合了useThemeuseMediaQuery

    编辑: useTheme 在这里并不是真正需要的,因为 useMediaQuery 会自动将其作为参数提供。

    // import { useTheme } from "@material-ui/core/styles";
    import { useMediaQuery } from "@material-ui/core";
    ...
    
    function ResponsiveButton() {
      // const theme = useTheme();
      // const isSmallScreen = useMediaQuery(theme.breakpoints.down("xs"));
      const isSmallScreen = useMediaQuery(theme => theme.breakpoints.down("xs"));
    
      const buttonProps = {
        variant: isSmallScreen ? "text" : "outlined",
        size: isSmallScreen ? "small" : "large"
      };
      return (
        <Button {...buttonProps} color="primary">
          Responsive Button
        </Button>
      );
    }
    
    export default ResponsiveButton;
    

    【讨论】:

    • 我已经这样做了,但它似乎不会随着窗口大小的调整而重新呈现。有什么建议吗?
    【解决方案2】:

    Material UI Docs:

    有时您可能希望根据断点值更改 React 渲染树。我们为此用例提供了一个 withWidth() 高阶组件。

    withWidthwidth 属性注入到您的组件中,使您可以访问当前断点值。这允许您根据屏幕尺寸呈现不同的道具或内容。

    function ResponsiveButton({ width }) {
      // This is equivalent to theme.breakpoints.down("sm")
      const isSmallScreen = /xs|sm/.test(width);
      const buttonProps = {
        variant: isSmallScreen ? "text" : "outlined",
        size: isSmallScreen ? "small" : "large"
      };
      return (
        <Button {...buttonProps} color="primary">
          Responsive Button
        </Button>
      );
    }
    
    export default withWidth()(ResponsiveButton);
    

    【讨论】:

    • 谢谢,卢克。太棒了!我确实阅读了该部分,但直到我看到您的示例才点击它。
    • 不幸的是,withWidth 在 v5 中已被弃用。现在有什么建议吗?
    【解决方案3】:

    这是我的实现

    import Button from "@material-ui/core/Button";
    import { useTheme } from "@material-ui/core/styles";
    import useMediaQuery from "@material-ui/core/useMediaQuery";
    import { useEffect } from "react";
    
    const ResponsiveButton = (props) => {
      const theme = useTheme();
      const desktop = useMediaQuery(theme.breakpoints.up("lg"));
      const tablet = useMediaQuery(theme.breakpoints.up("sm"));
      const mobile = useMediaQuery(theme.breakpoints.up("xs"));
    
      const sizes = () => {
        if (desktop) return "large";
        if (tablet) return "medium";
        if (mobile) return "small";
      };
    
      return <Button {...props} size={sizes()}/>;
    };
    export default ResponsiveButton;

    【讨论】:

    • 请在您的代码sn-p之外添加一些解释。您的解决方案的主要优势是什么?
    猜你喜欢
    • 1970-01-01
    • 2021-03-07
    • 2020-02-05
    • 1970-01-01
    • 1970-01-01
    • 2019-10-06
    • 1970-01-01
    • 2021-10-01
    • 1970-01-01
    相关资源
    最近更新 更多