使用基于主题的 Box 功能的可重用组件

IT技术 reactjs material-ui
2021-05-05 13:03:28

我想使用 Material-UI 的 api(不使用样式组件)创建一个可重用的组件。我做到了这一点 - 它几乎可以工作 - 但是使用主题变量的设置不起作用(例如,bgcolor 和 padding) . 我做错了什么 - 或者这是不可能的?

  const BigPanel = styled(Box)({
    display: 'flex',
    width: '100%',
    flexgrow: 1,
    bgcolor: 'background.paper',
    borderRadius: 10,
    boxShadow:'1',
    p:{ xs: 4, md: 8 }
  });
1个回答

传递给的对象styled是 CSS 属性,但您混合了 CSS 属性和Boxprops ( bgcolor, p)。即使是有效的 CSS 属性 ( display, width)也是有效的Boxprops,所以最直接的解决方案是将它们全部指定为 props。

处理此问题的一种方法是使用defaultProps这使得在使用组件时通过显式指定它们来覆盖某些 props 变得非常容易,如下例所示。

import React from "react";
import Box from "@material-ui/core/Box";
import CssBaseline from "@material-ui/core/CssBaseline";
import { styled } from "@material-ui/core/styles";

const BigPanel = styled(Box)({});
BigPanel.defaultProps = {
  display: "flex",
  width: "100%",
  borderRadius: 10,
  flexGrow: 1,
  bgcolor: "background.paper",
  p: { xs: 4, md: 8 },
  boxShadow: "1"
};
export default function App() {
  return (
    <>
      <CssBaseline />
      <BigPanel>Default BigPanel</BigPanel>
      <BigPanel bgcolor="primary.main" color="primary.contrastText">
        BigPanel with explicit props
      </BigPanel>
    </>
  );
}

编辑样式框

在上面的例子中,styled除了创建一个新的组件类型之外它不再真正用于任何目的。虽然它不是更少的代码,但下面是一种无需使用即可获得相同效果的替代方法styled

const BigPanel = React.forwardRef(function BigPanel(props, ref) {
  return <Box ref={ref} {...props} />;
});
BigPanel.defaultProps = {
  display: "flex",
  width: "100%",
  borderRadius: 10,
  flexGrow: 1,
  bgcolor: "background.paper",
  p: { xs: 4, md: 8 },
  boxShadow: "1"
};

编辑样式框(分叉)