@ bem- react/ core # # # 时间轴

核心软件包帮助组织和管理组件 BEM 修改器 在反应.
安装
npm i -S @bem-react/core
使用量
例如,您有一个初始的 App 文件结构如下:
App.tsx
Components/
Button/
Button.tsx
你需要设置两种可选的按钮类型,这些按钮不同于 Button.tsx。 。 。 . (在我们的例子中,这些将是主题"动作"和类型"link"的按钮)
你可以处理那些使用 @ bem- react/ core (英语)。 。 。 .
随入向导.
步骤1.
在你身边 Components/Button/index.tsx,您定义了按钮可以在延伸的界面中获取的道具类型 分类Name 从“ @ bem- react/ core” 开始 :
import { ReactType } from 'react'
import { IClassNameProps } from '@bem-react/core'
import { cn } from '@bem-react/classname'
export interface IButtonProps extends IClassNameProps {
as?: ReactType
}
export const cnButton = cn('Button')
步骤二.
设置 基本按钮 如果 无修改符 道具设置在母组件中.
在你体内 Components/Button/Button.tsx数字 :
import React, { FC } from 'react'
import { IButtonProps, cnButton } from './index'
export const Button: FC<IButtonProps> = ({
children,
className,
as: Component = 'button',
...props
}) => (
<Component {...props} className={cnButton({}, [className])}>
{children}
</Component>
)
步骤3.
设置 带有按钮TypeLink的选项 财务报告和审定财务报表 按钮主题动作选项 如果 {type: 'link'} 和(或) {theme: 'action'} 修改器分别设置在母组件中.
在你体内 Components/Button/ 您添加文件夹 _type/ 与 Button_type_link.tsx 文件中的文件和 _theme/ 与 Button_theme_action.tsx 。 。 。 .
App.tsx
Components/
Button/
Button.tsx
index.tsx
+ _type/
+ Button_type_link.tsx
+ _theme/
+ Button_theme_action.tsx
设置变体:
记着! 第二个参数在 withBemMod() 是应用此组件的条件.
1. 联合国. 单位 Components/Button/_type/Button_type_link.tsx
import React from 'react'
import { withBemMod } from '@bem-react/core'
import { IButtonProps, cnButton } from '../index'
export interface IButtonTypeLinkProps {
type?: 'link'
href?: string
}
export const withButtonTypeLink = withBemMod<IButtonTypeLinkProps, IButtonProps>(
cnButton(),
{ type: 'link' },
(Button) => (props) => <Button {...props} as="a" />,
)
2. 联合国. 单位 Components/Button/_theme/Button_theme_action.tsx
import { withBemMod } from '@bem-react/core'
import { cnButton } from '../index'
export interface IButtonThemeActionProps {
theme?: 'action'
}
export const withButtonThemeAction = withBemMod<IButtonThemeActionProps>(cnButton(), {
theme: 'action',
})
步骤4.
终于,在你 App.tsx 你需要帮助 编曲 只需要带基本按钮的变体.
注意进口订单 - 它直接影响您的 CSS 规则 .
注: 如果你想使用具有不同数值的同一种修饰符,则应使用
composeU用于正确输入.
import React, { FC } from 'react';
import { compose, composeU } from '@bem-react/core';
import { Button as ButtonPresenter } from './Components/Button/Button';
import { withButtonTypeLink } from './Components/Button/_type/Button_type_link';
import { withButtonThemeAction } from './Components/Button/_theme/Button_theme_action';
import { withButtonThemeDefault } from './Components/Button/_theme/Button_theme_default';
import './App.css';
const Button = compose(
composeU(withButtonThemeAction, withButtonThemeDefault),
withButtonTypeLink,
)(ButtonPresenter);
export const App: FC = () => (
<div className="App">
<Button>I'm basic</Button>
// Renders into HTML as: <button class="Button">I'm Basic</button>
<Button type="link" href="#stub">I'm type link</Button>
// Renders into HTML as: <a href="#stub" class="Button Button_type_link">I'm type link</a>
<Button theme="action">I'm theme action</Button>
// Renders into HTML as: <button class="Button Button_theme_action">I'm theme action</button>
<Button theme="action" type="link">I'm all together</Button>
// Renders into HTML as: <a class="Button Button_theme_action Button_type_link">I'm all together</a>
</div>
);
记着! 在按钮Presenter上构成的可选组件的顺序很重要:如果您的布局不同,需要应用多个修改符,则 首个 一个在作曲方法内 将会得到! 例如,这里:
export const Button = compose(
withButtonThemeAction,
withButtonTypeLink,
)(ButtonPresenter)
如果你和Button的动作有点像
<button className={className}>{children}</button>
您的JSX组件:
<Button type="link" theme="action">Hello</Button>
将生成 HTML :
<a class="Button Button_theme_action Button_type_link">Hello</a>
使用再出口来改进DX
关键是: 如果 树摇晃 启用
示例
Block/Block.tsx
Block/[email protected]
Block/_mod/Block_mod_val1.tsx
Block/_mod/Block_mod_val2.tsx
Block/_mod/Block_mod_val3.tsx
按平台为索引文件中的所有修饰符创建再导出:桌面,电话,amp等.
// Block/index.ts
export * from './Block'
export * from './Block/_mod'
// Block/desktop.ts
export * from './Block@desktop'
export * from './Block/_mod'
// Block/phone.ts
export * from './' // for feature if not created platform version
// Block/_mod/index.ts
export * from './Block_mod_val1.tsx'
export * from './Block_mod_val2.tsx'
export * from './Block_mod_val3.tsx'
用法 :
// App.tsx
import { Block as BlockPresenter, withModVal1 } from './components/Block/desktop'
const Block = withModVal1(BlockPresenter)
优化. 懒惰负载为修饰剂.
用React.lazy和动态导入来分拆更好的代码的解决方案
页:1 如果您需要 SSR 替换 React.lazy 装载方法
Block_mod.async.tsx模块改为 @ 可装入/ 组件 或者说 可反应加载
// Block/_mod/Block_mod.async.tsx
import React from 'react'
import { cnBlock } from '../Block'
import './Block_mod.css'
export const DynamicPart: React.FC = () => <i className={cnBlock('Inner')}>Loaded dynamicly</i>
// default export needed for React.lazy
export default DynamicPart
// Block/_mod/Block_mod.tsx
import React, { Suspense, lazy } from 'react'
import { cnBlock } from '../Block'
export interface BlockModProps {
mod?: boolean
}
export const withMod = withBemMod<BlockModProps>(cnBlock(), { mod: true }, (Block) => (props) => {
const DynamicPart = lazy(() => import('./Block_mod.async.tsx'))
return (
<Suspense fallback={<div>Updating...</div>}>
<Block {...props}>
<DynamicPart />
</Block>
</Suspense>
)
})
用法 :
// App.tsx
import {
Block as BlockPresenter,
withMod
} from './components/Block/desktop';
const Block = withMod(BlockPresenter);
export const App = () => {
return (
{/* chunk with DynamicPart not loaded */}
<Block />
{/* chunk with DynamicPart loaded */}
<Block mod />
);
}
简单修改器( 仅属于 CSS 类)
在大多数情况下,您只需要更改 CSS 类。 这种模式不会将modififer值传递给道具. 它不会为组件创建回声包,这样更好.
import React from 'react'
import { cnBlock } from '../Block'
export interface BlockModProps {
simplemod?: boolean
}
export const withSimpleMod = createClassNameModifier<BlockModProps>(cnBlock(), { simplemod: true })
调试
帮助您调试“ @ bem- react/ core” 支持开发模式 .
对于 <Button type="link" theme="action">Hello</Button> (从 示例 ), React DevTools 将显示:
<WithBemMod(Button)[theme:action] ...>
<WithBemMod(Button)[type:link] className="Button Button_theme_action" ...>
<a className="Button Button_type_link Button_theme_action">Hello</a>
</WithBemMod(Button)[type:link]>
</WithBemMod(Button)[theme:action]>