簡體   English   中英

如何使用 Typescript 實現 Material-UI ThemeProvider 和 WithStyles

[英]How to implement Material-UI ThemeProvider and WithStyles using Typescript

我越來越沮喪,因為過去幾天我一直在嘗試將我的 React 應用程序從 javascript 遷移到 tsx。 到目前為止,我喜歡 tsx 的類型檢查,但我不相信 material-ui 庫很好,因為它解釋了如何在打字稿中使用其樣式。

我已經按照這里的指南https://material-ui.com/guides/typescript/寫信並創建了一個主題:

import { createMuiTheme } from "@material-ui/core/styles";

export default function theme() {
  return createMuiTheme({
  palette: {
    primary: {
      main: "#607D8B",
      light: "#CFD8DC",
      dark: "#455A64",
      contrastText: "#FFFFFF"
    },
    secondary: {
      main: "#7C4DFF",
      contrastText: "#212121"
    }
  }
})};

我創造了一種風格:

import { green, red } from "@material-ui/core/colors";
import { createStyles, withStyles } from "@material-ui/core/styles";
import { Theme } from '@material-ui/core';

const useStyles = (theme: Theme) => createStyles({
  root: {
    height: "100vh"
  },
  success: {
    backgroundColor: green[600]
  },
  error: {
    backgroundColor: red[800]
  },
  icon: {
    fontSize: 20
  },
  iconVariant: {
    opacity: 0.9,
    marginRight: theme.spacing(1)
  },
  message: {
    display: "flex",
    alignItems: "center"
  },
  image: {
    backgroundImage: "url(https://source.unsplash.com/8WFnEehJWso)",
    backgroundRepeat: "no-repeat",
    backgroundColor: theme.palette.primary.light,
    backgroundSize: "cover",
    backgroundPosition: "center"
  },
  paper: {
    height: "30vh",
    margin: theme.spacing(1.5, 3),
    display: "flex",
    flexDirection: "column",
    alignItems: "center"
  },
  mui_form: {
    width: "100%",
    marginTop: theme.spacing(1)
  },
  submit: {
    margin: theme.spacing(3, 0, 2)
  },
  card: {
    maxWidth: 600
  },
  media: {
    height: 500
  },
  circle: {
    display: "flex",
    "& > * + *": {
      marginLeft: theme.spacing(2)
    },
    align: "center"
  },
  menuButton: {
    marginRight: theme.spacing(2)
  },
  title: {
    flexGrow: 1,
    alignContent: "center"
  },
  pie: {
    height: 250,
    marginBottom: theme.spacing(2)
  },
  avatar: {
    margin: theme.spacing(1),
    backgroundColor: theme.palette.secondary.main
  },
  muiform: {
    width: "100%", // Fix IE 11 issue.
    marginTop: theme.spacing(1),
    "&:focus": {
      borderColor: "primary.dark"
    }
  },
  muisubmit: {
    margin: theme.spacing(3, 0, 2),
    padding: theme.spacing(3, 2),
    background: "primary.main",
    "&:hover": {
      backgroundColor: "primary.dark"
    }
  },
  login: {
    padding: "0 30px",
    height: 200,
    display: "flex",
    flexDirection: "column",
    justifyContent: "center"
  },
  loginImage: {
    backgroundImage: "url(https://source.unsplash.com/rCbdp8VCYhQ)",
    backgroundRepeat: "no-repeat",
    backgroundSize: "cover",
    backgroundPosition: "center",
    height: "100vh"
  },
  loginSurface: {
    height: "40vh",
    padding: "20px 10px",
    display: "flex",
    flexDirection: "column",
    alignItems: "center",
    background: "black"
  },
  table: {
    minWidth: 650
  }
});

export default withStyles(useStyles);

然后我嘗試在一個組件上實現這個:

import DialogContent from "@material-ui/core/DialogContent";
import DialogContentText from "@material-ui/core/DialogContentText";
import DialogTitle from "@material-ui/core/DialogTitle";
import Slide from "@material-ui/core/Slide";
import Table from "@material-ui/core/Table";
import TableBody from "@material-ui/core/TableBody";
import TableCell from "@material-ui/core/TableCell";
import TableContainer from "@material-ui/core/TableContainer";
import TableHead from "@material-ui/core/TableHead";
import TableRow from "@material-ui/core/TableRow";
import Paper from "@material-ui/core/Paper";
import useStyles from "./useStyles";
import { TransitionProps } from "@material-ui/core/transitions";
import { useTheme } from '@material-ui/core/styles';
import { Theme } from '@material-ui/core';

const Transition = React.forwardRef<unknown, TransitionProps>(
  function Transition(props, ref) {
    return <Slide direction="up" ref={ref} {...props} />;
  }
);

export default function GuidanceDialogue(){
  const theme = useTheme<Theme>();
  const [open, setOpen] = React.useState(false);
  const classes = useStyles(theme);

主題使用 useTheme 訪問,並使用根 App.js 中的 ThemeProvider 傳遞。

我得到的錯誤是:

const classes = useStyles(theme);

“主題”類型的參數不可分配給“組件類型”類型的參數; }>>'。 “主題”類型不可分配給“功能組件”類型; }>>'。 類型 'Theme' 不匹配簽名 '(props: PropsWithChildren; }>>, context?: any): ReactElement<...> | null'.ts(2345)

如果我將類型轉換為如下:

const classes = useStyles<any>(theme);

所以我可以看到類型錯誤是否真的是問題,或者還有其他事情發生,然后它提到我指的 className 屬性,例如 classes.table, table 不存在。

我對整件事很困惑,請幫忙!

解決方案是編寫以下樣式文件:

 const useStyles = makeStyles((theme: Theme) => createStyles({
  root: {

createStyles、makeStyles 的文檔

通過運行下面的代碼,我未能重現您的類型錯誤。

import { Theme, useTheme, makeStyles } from "@material-ui/core";

const useStyles = makeStyles((theme: Theme) => ({
  root: {}
}));

export default function App() {
  const theme = useTheme<Theme>();
  const classes = useStyles(theme);
  return (
    <div className="App">
      <h1 className={classes.root}>Theme</h1>
    </div>
  );
}

在線試一下:

編輯 kind-robinson-3j05i

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM