React Material-UI 中“makeStyles”的内部实现?

IT技术 reactjs material-ui
2021-03-24 03:33:35

这个问题的目的是了解幕后发生的事情。每次我找到代码时,makeStyles()我都觉得我只是在做一个纯粹的复制粘贴,而不了解幕后发生的事情。所以我想在这里发布一个问题,以便有人可以帮助我。

我在许多 React 应用程序中看到过以下类型的代码。当我们打电话给 时,我很想知道发生了什么makeStyles()所以我跳入了它的定义,但我无法理解它的含义。有人可以帮助我理解如何阅读/理解它。

我在这里理解的是,我正在传递一个名为theme. 通过该函数后,我不知道发生了什么。如果有人也帮我弄清楚这一点,我将不胜感激。

// Calling makeStyles()
const useStyles = makeStyles(theme => ({
  root: {
    display: 'flex',
  },
  drawer: {
    [theme.breakpoints.up('sm')]: {
      width: drawerWidth,
      flexShrink: 0,
    },
  },
  appBar: {
    marginLeft: drawerWidth,
    [theme.breakpoints.up('sm')]: {
      width: `calc(100% - ${drawerWidth}px)`,
    },
  },
  menuButton: {
    marginRight: theme.spacing(2),
    [theme.breakpoints.up('sm')]: {
      display: 'none',
    },
  },
  toolbar: theme.mixins.toolbar,
  drawerPaper: {
    width: drawerWidth,
  },
  content: {
    flexGrow: 1,
    padding: theme.spacing(3),
  },
}));

//definition of makeStyles()
import { Theme as DefaultTheme } from './createMuiTheme';
import { Styles, WithStylesOptions } from '@material-ui/styles/withStyles';
import { StylesHook } from '@material-ui/styles/makeStyles';

export default function makeStyles<
  Theme = DefaultTheme,
  Props extends {} = {},
  ClassKey extends string = string
>(
  styles: Styles<Theme, Props, ClassKey>,
  options?: WithStylesOptions<Theme>,
): StylesHook<Styles<Theme, Props, ClassKey>>;
2个回答

输入/输出/副作用的高级图片

制作样式

  • 概述:此函数通常在 JavaScript 文件的顶层调用(而不是从组件/函数中调用),它返回一个函数(通常称为useStyles),该函数将在函数组件中使用。
  • 输入:样式对象或样式对象创建者函数
    • 如果输入是一个对象,则假定该对象的每个属性都定义了一个样式规则。属性名称是规则名称,属性值是具有 CSS 属性和/或嵌套规则的对象。每个样式规则稍后将用于生成 CSS 类。
    • 如果输入是一个函数,则假定它是一个函数,它接收主题作为参数,然后返回一个样式对象,其结构在输入是对象的情况下描述。
    • makeStyles 函数声明中,此输入被调用stylesOrCreator然后由getStylesCreator 函数将其规范化为具有create指向将返回样式对象的函数属性的对象。
  • 输出:useStyles函数
    • 该函数返回makeStyles通常被称为useStyles是一个自定义的钩子这意味着它只能从函数组件内部调用,并且必须无条件调用
    • 在返回此useStyles函数时,几乎没有发生任何事情。该函数知道它的stylesCreator,但尚未使用它。通过styleCreator 的 options,该useStyles函数知道一个index,稍后将用于确定<head>这些样式相对于其他调用makeStyles/生成的其他样式表在样式表中的位置useStyles
  • 副作用:增加一个全局计数器,用于确定由<head>生成的样式表中的索引makeStyles/useStyles

使用样式

  • 概述:这是由 返回的函数makeStyles应该从函数组件中调用它以获取classes下面描述对象。
  • 可选输入:props对象
  • 输出:classes对象
    • 此对象将样式对象中的每个样式规则名称映射到生成的 CSS 类名称。然后classes.rulename您可以利用组件渲染将该 CSS 类应用于元素。
  • 副作用:在<head>每个样式规则包含一个 CSS 类的 DOM 中添加一个样式表

主要工作发生的地方

当您调用该useStyles函数时,会发生大部分魔术函数的开头在这里以下是它执行的关键步骤:

是否可以在另一个组件中重用 useStyles?我的意思是,如果我导出这个钩子并在多个组件中使用它,可以吗?
2021-06-05 03:33:35
@MichaelGustus 是的,但有一些警告。见我的答案在这里:stackoverflow.com/questions/56929702/...
2021-06-12 03:33:35

makeStyles(styles, [options]) => hook 使用钩子模式将样式表与功能组件链接起来。

参数

  1. 样式(函数|对象):生成样式或样式对象的函数。它将链接到组件。如果您需要访问主题,请使用函数签名。它作为第一个参数提供。

  2. 选项(对象[可选]):options.defaultTheme(对象[可选]):

    1.如果主题不是通过主题提供者提供的,则使用默认主题。

    1. options.name (String [可选]):样式表的名称。用于调试。如果未提供该值,它将尝试回退到组件的名称。
    2. options.flip(Boolean [可选]):当设置为 false 时,此工作表将选择退出 rtl 转换。设置为 true 时,样式将反转。当设置为 null 时,它遵循 theme.direction。

    其他键被转发到jss.createStyleSheet([styles], [options])的 options 参数 . 返回钩子:一个钩子。这个钩子可以在函数组件中使用。文档通常将这个返回的钩子称为 useStyles。它接受一个参数:将用于样式表中“插值”的属性。

例子

import React from 'react';
import { makeStyles } from '@material-ui/styles';

const useStyles = makeStyles({
  root: {
    backgroundColor: 'red',
    color: props => props.color,
  },
});

export default function MyComponent(props) {
   const classes = useStyles(props);
   return <div className={classes.root} />;  
}