JSS与React的集成
时间:2022-12-21 15:00:00
介绍
React-JSS使用新的Hooks API将JSS与React集成在一起。 JSS默认预设已内置。
从v基于10,不支持HOC的API,并在所有即将发布的主要版本中删除。不支持以下使用方法。
import React from 'react' import {render} from 'react-dom' import withStyles from 'react-jss' // 1、创建styles const styles = { ... } // 使用这些样式来定义组件,并将其传递给classes用它来分配作用域类名 const Button = ({classes, children}) => ( ) // 3、最后,将样式表注入组件 const StyledButton = withStyles(styles)(Button) // 或 4、导出组件 export default withStyles(styles)(Button) // 5、使用 const App = () => Submit render( , document.getElementById('root'))
直接使用核心JSS软件包相比,其好处是:
- 动态主题-在传播和运行时允许基于上下文的主题更新。
- 关键CSS只从呈现的组件中提取CSS。
- 惰性评估-样式表是在安装组件时创建的,卸载组件时删除的。
- 样式表的静态部分将在所有元素之间共享。
- 函数值和规则将由您传递useStyles(data)自动更新任何数据。例如,您可以传输道具、状态或上下文中的任何内容。
基本使用
import React from 'react' import {render} from 'react-dom' import {createUseStyles} from 'react-jss' // 1、创建样式 const useStyles = createUseStyles({ myButton: { color: 'green', margin: { // jss-plugin-expand插件使语法可读性更高 top: 5, // jss-plugin-default-unit插件补充单位 right: 0, bottom: 0, left: '1rem' }, '& span': { // jss-plugin-nested 插件将样式应用到子节点 fontWeight: 'bold' // jss-plugin-camel-case插件将fontWegith转化为font-weight } }, myLabel: { fontStyle: 'italic' }, }) // 2.使用这些样式定义组件并将其传递给classes属性,用它来分配作用域名 const Button = ({children}) => { const classes = useStyles() // 使用样式 return ( ) } // 3、使用组件 const App = () => render( , document.getElementById('root'))
上面的代码编译成
.myButton-0-1-24 { color: green; margin: 5px 0 0 1rem; } .myButton-0-1-24 span { font-weight: bold; } .myLabel-0-1-87 { font-style: italic; }
动态值
您可以直接使用函数值、函数规则和观察对象。一旦组件第一次收到新的props或mount,接收函数值和函数规则props对象。
注意事项:
首先呈现静态属性,使函数值具有较高的源顺序特异性:
import React from 'react' import {createUseStyles} from 'react-jss' const useStyles = createUseStyles({ myButton: { padding: props => props.spacing }, myLabel: props => ({ display: 'block', color: props.labelColor, fontWeight: props.fontWeight, fontStyle: props.fontStyle }) }) const Button = ({children, ...props}) => { const classes = useStyles(props) return ( ) } Button.defaultProps = { spacing: 10, fontWeight: 'bold', labelColor: 'red' } const App = () =>
上面的代码编译成
.Button-myButton-1-25 { padding: 10px; } .Button-myLabel-1-26 { display: block; color: red; font-weight: bold; font-style: italic; }
主题化
主题化指定一个主题ThemeProvider
包装应用程序,然后将主题对象传递给ThemeProvider
。以后,您可以在样式创建器函数(createUseStyles ((theme) => { ... })
)中使用useTheme()
链接访问主题。之后,您可以更改主题,所有组件将自动获得新主题。
在幕后,react-jss为React使用独立的主题解决方案。您可以在回购中找到完整的文档。
ThemeProvider
的用法:
- 它有一个
theme
prop,使用一个object
或function
表示:
- 假如是一个
Object
并在根ThemeProvider
使用时,它是完整的,并向下传递React Tree
。- 如果它是Object并在嵌套的
ThemeProvider中
使用时,它会和父亲在一起ThemeProvider
主题合并,向下传递React Tree
。- 如果它是
Function
并在嵌套的ThemeProvide
r如果时,它将从父亲身上使用``ThemeProvider主题应用。如果结果是一个
Object,它将沿着
React Tree```向下传递,否则抛出。
ThemeProvider
和所有其他组件一样,只能渲染一个child
,因为它用于渲染React.Children.only
,否则抛出。
import React from 'react' import {createUseStyles, useThem, ThemeProvider} from 'react-jss'
// 1、当有很多主题依赖关系时,最好使用theme函数
let useStyles = createUseStyles(theme => ({
button: {
background: theme.colorPrimary
},
label: {
fontWeight: 'bold'
}
}))
// 或者如果只有很少的主题相关样式,则使用函数值可能会更好,并且props或state也用于其他值
useStyles = createUseStyles({
button: {
background: ({theme}) => theme.colorPrimary
},
label: {
fontWeight: 'bold'
}
})
// 2、定义组件,传入theme、props等
const Button = ({children, ...props}) => {
const theme = useTheme()
const classes = useStyles({...props, theme})
return (
)
}
const theme = {
colorPrimary: 'green'
}
// 定义主题及使用组件
const App = () => (
)
使用自定义主题上下文
使用命名空间主题,这样一组UI组件就不会与其他库中的另一组UI组件发生冲突(也可以使用react-jss
),或者如果你想从应用程序中已使用的另一个上下文中使用同一主题,则不会发生冲突。
import React from 'react'
import {createUseStyles, createTheming} from 'react-jss'
const ThemeContext = React.createContext({})
// 创建一个具有命名空间的主题对象
const theming = createTheming(ThemeContext)
// 注意这里的useTheme来自theming对象,而不是来自react-jss导入。
const {ThemeProvider, useTheme} = theming
const useStyles = createUseStyles(
{
button: {
background: ({theme}) => theme.colorPrimary
}
// 将theming对象传递给createUseStyles()
},
{theming}
)
const myTheme = {
colorPrimary: 'green'
}
const Button = ({children, ...props}) => {
const theme = useTheme()
const classes = useStyles({...props, theme})
return
}
const OtherLibraryThemeProvider = () => null
const OtherLibraryComponent = () => null
const otherLibraryTheme = {}
// 使用具有命名空间的主题ThemeProviders-它们可以以任何顺序嵌套
const App = () => (
)
类名生成器选项
确保在服务器和客户端上使用相同的设置。ID生成器用于类名和关键帧。
1、你可以通过传递自定义生成器函数来更改类名称生成算法。
import React from 'react'
import ReactDOM from 'react-dom'
import {JssProvider} from 'react-jss'
import MyApp from './MyApp'
const generateId = (rule, sheet) => 'some-id'
ReactDOM.render(
,
document.getElementById('root')
)
2、你可以为每个类添加其他前缀,详见。
3、你可以通过传递id
属性来最小化类名,详见。
import React from 'react'
import ReactDOM from 'react-dom'
import {JssProvider} from 'react-jss'
import MyApp from './MyApp'
ReactDOM.render(
{minify: true}}>
,
document.getElementById('root')
)
服务端渲染
挂载应用程序后,应删除关键CSS呈现的服务器端使用的样式标签。
import React from 'react'
import {renderToString} from 'react-dom/server'
import {JssProvider, SheetsRegistry, createGenerateId} from 'react-jss'
import MyApp from './MyApp'
export default function render(req, res) {
const sheets = new SheetsRegistry()
const generateId = createGenerateId()
const body = renderToString(
)
//任何在 中使用useStyles的实例都将获得样式表
return res.send(
renderToString(
{body}
)
)
}