React Material-UI 中“makeStyles”的内部实现?
Posted
技术标签:
【中文标题】React Material-UI 中“makeStyles”的内部实现?【英文标题】:Internal implementation of "makeStyles" in React Material-UI? 【发布时间】:2019-12-04 19:11:49 【问题描述】:这个问题的目的是了解幕后发生的事情。每次我找到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% - $drawerWidthpx)`,
,
,
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>>;
【问题讨论】:
【参考方案1】:输入/输出/副作用的高级图片
制作样式
概述:此函数通常在 javascript 文件的顶层调用(而不是从组件/函数内),它返回一个函数(通常称为useStyles
),该函数将在函数组件内使用.
输入:样式对象或样式对象创建函数
如果输入是一个对象,则假定该对象的每个属性都定义了一个样式规则。属性名称是规则名称,属性值是具有 CSS 属性和/或嵌套规则的对象。每个样式规则稍后将用于生成 CSS 类。
如果输入是一个函数,则假定它是一个函数,该函数接收主题作为参数,然后返回一个样式对象,该对象具有在输入为对象的情况下描述的结构。
在makeStyles function declaration 中,此输入称为stylesOrCreator
。然后通过getStylesCreator function 将其标准化为具有create
属性的对象,该属性指向将返回样式对象的函数。
输出:useStyles
函数
makeStyles
的函数returned 通常称为useStyles
,是一个custom hook。这意味着它只能从函数组件和must be called unconditionally 中调用。
在返回此useStyles
函数时,几乎没有发生任何事情。该函数知道它的stylesCreator,但还没有使用它。通过stylesCreator's options,useStyles
函数知道index
稍后将用于确定这些样式相对于其他对@987654352 的调用生成的其他样式表在样式表的<head>
中的位置@/useStyles
.
副作用:增加一个global counter,用于确定<head>
中由makeStyles/useStyles
生成的样式表的索引。
使用样式
概述:这是makeStyles
返回的函数。应该从函数组件中调用它以获取如下所述的classes
对象。
可选输入:props
对象
如果传递,这通常是函数组件的props
。然后它将作为参数传递给值是函数的任何样式规则。
您可以在以下答案中看到使用此功能的示例:
Send Variable to withStyles in Material UI?
Using props to set '&:hover' background-color
How to use 'theme' and 'props' in makeStyles?
输出:classes
对象
此对象将样式对象中的每个样式规则名称映射到生成的 CSS 类名称。然后,您可以在组件渲染中利用 classes.rulename
将该 CSS 类应用于元素。
副作用:将样式表添加到 <head>
中的 DOM,其中包含每个样式规则的 CSS 类。
主要工作发生在哪里
大部分魔法发生在您调用useStyles
函数时。函数的开头是here。以下是它执行的关键步骤:
classes
对象中的类名。
Attaches 将此样式表添加到 DOM 中的 <head>
内的适当位置。
Returns the classes object
如果发生触发重新创建 CSS 或组件卸载的情况,则调用 detach 以删除先前生成的样式表。
【讨论】:
是否可以在另一个组件中重用 useStyles?我的意思是,如果我导出这个钩子并在几个组件中使用它,可以吗? @MichaelGustus 是的,但有一些警告。在这里查看我的答案:***.com/questions/56929702/…。【参考方案2】:makeStyles(styles, [options]) => 钩子 使用钩子模式将样式表与功能组件链接。
参数
styles (Function | Object):生成样式或样式对象的函数。它将链接到组件。如果您需要访问主题,请使用函数签名。它作为第一个参数提供。
选项(对象 [可选]): options.defaultTheme(对象 [可选]):
1.如果主题不是通过主题提供者提供时使用的默认主题。
-
options.name(字符串 [可选]):样式表的名称。对...有用
调试。如果未提供该值,它将尝试回退到该名称
组件。
options.flip (Boolean [optional]): 当设置为 false 时,此工作表将选择 -
退出 rtl 转换。设置为 true 时,样式会反转。什么时候
设置为null,它遵循theme.direction。
其他键被转发到选项参数 jss.createStyleSheet([styles], [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 />;
【讨论】:
以上是关于React Material-UI 中“makeStyles”的内部实现?的主要内容,如果未能解决你的问题,请参考以下文章
React & Material-UI 分页 - 将 Material-UI 的组件连接到 React-Router
如何在 React 测试库中获取 Material-UI 密码输入
在 Material-ui 中使用 mixins 自定义 React 中的组件
React + Jest单元测试中的Material-UI排版错误