Era*_*uwa 138 node.js react-jsx
我尝试编写一个React组件.对于html标题标签(h1,h2,h3等),其中标题优先级根据我们在props中定义的优先级动态变化.
这就是我尝试做的事情.
<h{this.props.priority}>Hello</h{this.props.priority}>
预期产量:
<h1>Hello</h1>
这不起作用.有没有可行的方法来做到这一点?
zer*_*kms 279
无法在原地进行,只需将其放入变量(首字母大写):
const CustomTag = `h${this.props.priority}`;
<CustomTag>Hello</CustomTag>
Run Code Online (Sandbox Code Playgroud)
Jac*_*eam 72
如果您使用 TypeScript,您会看到如下错误:
Type '{ children: string; }' has no properties in common with type 'IntrinsicAttributes'.ts(2559)
TypeScript 不知道这CustomTag是一个有效的 HTML 标签名称,并抛出一个无用的错误。
要修复,请强制转换CustomTag为keyof JSX.IntrinsicElements!
const CustomTag = `h${this.props.priority}` as keyof JSX.IntrinsicElements;
<CustomTag>Hello</CustomTag>
Run Code Online (Sandbox Code Playgroud)
Fel*_*ing 25
为了完整性,如果要使用动态名称,也可以直接调用React.createElement而不是使用JSX:
React.createElement(`h${this.props.priority}`, null, 'Hello')
Run Code Online (Sandbox Code Playgroud)
这避免了必须创建新变量或组件.
有道具:
React.createElement(
`h${this.props.priority}`,
{
foo: 'bar',
},
'Hello'
)
Run Code Online (Sandbox Code Playgroud)
来自文档:
创建并返回给定类型的新React元素.type参数可以是标记名称字符串(例如
'div'or'span'),也可以是React组件类型(类或函数).用JSX编写的代码将转换为使用
React.createElement().React.createElement()如果您使用的是JSX,通常不会直接调用.请参阅React Without JSX以了解更多信息.
rob*_*uck 12
在动态标题(h1, h2...)的实例中,组件可以像这样返回(上面由FelixReact.createElement提到)。
const Heading = ({level, children, ...props}) => {
return React.createElement('h'.concat(level), props , children)
}
Run Code Online (Sandbox Code Playgroud)
为了可组合性,道具和子项都被传递。
所有其他答案都工作正常,但我会添加一些其他内容,因为这样做:
标题组件:
import React from 'react';
const elements = {
h1: 'h1',
h2: 'h2',
h3: 'h3',
h4: 'h4',
h5: 'h5',
h6: 'h6',
};
function Heading({ type, children, ...props }) {
return React.createElement(
elements[type] || elements.h1,
props,
children
);
}
Heading.defaultProps = {
type: 'h1',
};
export default Heading;
Run Code Online (Sandbox Code Playgroud)
你可以像这样使用它
<Heading type="h1">Some Heading</Heading>
Run Code Online (Sandbox Code Playgroud)
或者您可以有一个不同的抽象概念,例如,您可以定义一个尺寸道具,例如:
import React from 'react';
const elements = {
xl: 'h1',
lg: 'h2',
rg: 'h3',
sm: 'h4',
xs: 'h5',
xxs: 'h6',
};
function Heading({ size, children }) {
return React.createElement(
elements[size] || elements.rg,
props,
children
);
}
Heading.defaultProps = {
size: 'rg',
};
export default Heading;
Run Code Online (Sandbox Code Playgroud)
你可以像这样使用它
<Heading size="sm">Some Heading</Heading>
Run Code Online (Sandbox Code Playgroud)
这就是我为我的项目设置的方式。
TypographyType.ts
import { HTMLAttributes } from 'react';
export type TagType = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'p' | 'span';
export type HeadingType = HTMLAttributes<HTMLHeadingElement>;
export type ParagraphType = HTMLAttributes<HTMLParagraphElement>;
export type SpanType = HTMLAttributes<HTMLSpanElement>;
export type TypographyProps = (HeadingType | ParagraphType | SpanType) & {
variant?:
| 'h1'
| 'h2'
| 'h3'
| 'h4'
| 'h5'
| 'h6'
| 'body1'
| 'body2'
| 'subtitle1'
| 'subtitle2'
| 'caption'
| 'overline'
| 'button';
};
Run Code Online (Sandbox Code Playgroud)
版式.tsx
import { FC } from 'react';
import cn from 'classnames';
import { typography } from '@/theme';
import { TagType, TypographyProps } from './TypographyType';
const headings = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'];
const paragraphs = ['body1', 'body2', 'subtitle1', 'subtitle2'];
const spans = ['button', 'caption', 'overline'];
const Typography: FC<TypographyProps> = ({
children,
variant = 'body1',
className,
...props
}) => {
const { variants } = typography;
const Tag = cn({
[`${variant}`]: headings.includes(variant),
[`p`]: paragraphs.includes(variant),
[`span`]: spans.includes(variant)
}) as TagType;
return (
<Tag
{...props}
className={cn(
{
[`${variants[variant]}`]: variant,
},
className
)}
>
{children}
</Tag>
);
};
export default Typography;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
41979 次 |
| 最近记录: |