我可以创建条件来渲染 React 组件/元素吗?
Can I create a condition to render an React component / element?
我想渲染一个基于 prop 的组件。
const Item = ({ property }) => {
return property ? <h1>...</h1> : <h6>...</h6>
}
在我的代码中,元素有父元素和子元素。所以我想知道这样的事情是否可能:
const Item = ({ property }) => {
element = property ? <h1> : <h6>
return <element>...</element>
}
我知道我可以包装父 + 子组件,但我正在寻找一个更具可读性和可维护性的解决方案。
这是我的组件:
import { IconProp } from "@fortawesome/fontawesome-svg-core"
import { faFolder } from "@fortawesome/free-solid-svg-icons"
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
import { Link } from "react-router-dom"
type ListItemProps = {
/** Set to true if element should have background */
background?: boolean
/** Set to true if element should be indented */
indent?: boolean
/** Title of an List Element is at the left side */
title: string
/** Icon at the beginning of the Element */
icon?: IconProp
/** Content on the left side next to title */
header?: React.ReactChild
/** Link to when click element */
to?: string
/** Function what happens when you click element */
onClick?: (values: any) => void
}
/**
* List, should have List as parent
*/
export const ListItem: React.FC<ListItemProps> = ({ title, icon = faFolder, indent, background, header, children, to, onClick }) => {
// Elements on the left side of the item
const headerContent = <>
<FontAwesomeIcon icon={icon} className="text-lightgrey mr-4" />
<h4 className="text-lg text-headline-black font-semibold mr-4">{title}</h4>
{header}
</>
const headerClasses = `flex items-center py-4 pl-7 ${indent ? "pl-16" : ""} flex-grow`
return <div className={`flex rounded-lg w-full cursor-pointer ${background ? "bg-white-lightgrey hover:bg-gray-200" : "hover:bg-white-lightgrey"}`}>
{to ?
<Link to={to} className={headerClasses}>
{headerContent}
</Link>
:
<button onClick={onClick} className={headerClasses}>
{headerContent}
</button>
}
{children && <div className="flex items-center mx-4">
{children}
</div>}
</div>
}
执行此操作有 2 个选项:
- 使用类似于您共享的伪代码的动态元素。你可以有条件地选择元素,你只需要像这样使用标签的名称作为 string (免责声明:我不知道这是多么传统)
注意:组件的变量名称(在本例中为Component
)需要大写或使用点符号访问。 <Component />
或 <someObject.component />
会起作用,但 <component />
不会。
function Item({prop}) {
const Component = prop ? 'h1' : 'h6'
return <Component>
<div>It works!</div>
</Component>
}
此解决方案也适用于自定义反应组件而不是 HTML 标签。看起来像这样
function FuncComponent() {}
function OtherComponent() {}
function Item({prop}) {
const Component = prop ? FuncComponent : OtherComponent
return <Component>
<div>It works!</div>
</Component>
}
- 首先在
return
语句之前渲染子元素,然后将其作为子元素提供给您想要的元素
function Item({prop}) {
const children = <div>It works!</div>
return {prop ? <h1>{children}</h1> : <h6>{children}</h6>}
}
这些都行,就看你喜欢哪个了。
我想渲染一个基于 prop 的组件。
const Item = ({ property }) => {
return property ? <h1>...</h1> : <h6>...</h6>
}
在我的代码中,元素有父元素和子元素。所以我想知道这样的事情是否可能:
const Item = ({ property }) => {
element = property ? <h1> : <h6>
return <element>...</element>
}
我知道我可以包装父 + 子组件,但我正在寻找一个更具可读性和可维护性的解决方案。
这是我的组件:
import { IconProp } from "@fortawesome/fontawesome-svg-core"
import { faFolder } from "@fortawesome/free-solid-svg-icons"
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
import { Link } from "react-router-dom"
type ListItemProps = {
/** Set to true if element should have background */
background?: boolean
/** Set to true if element should be indented */
indent?: boolean
/** Title of an List Element is at the left side */
title: string
/** Icon at the beginning of the Element */
icon?: IconProp
/** Content on the left side next to title */
header?: React.ReactChild
/** Link to when click element */
to?: string
/** Function what happens when you click element */
onClick?: (values: any) => void
}
/**
* List, should have List as parent
*/
export const ListItem: React.FC<ListItemProps> = ({ title, icon = faFolder, indent, background, header, children, to, onClick }) => {
// Elements on the left side of the item
const headerContent = <>
<FontAwesomeIcon icon={icon} className="text-lightgrey mr-4" />
<h4 className="text-lg text-headline-black font-semibold mr-4">{title}</h4>
{header}
</>
const headerClasses = `flex items-center py-4 pl-7 ${indent ? "pl-16" : ""} flex-grow`
return <div className={`flex rounded-lg w-full cursor-pointer ${background ? "bg-white-lightgrey hover:bg-gray-200" : "hover:bg-white-lightgrey"}`}>
{to ?
<Link to={to} className={headerClasses}>
{headerContent}
</Link>
:
<button onClick={onClick} className={headerClasses}>
{headerContent}
</button>
}
{children && <div className="flex items-center mx-4">
{children}
</div>}
</div>
}
执行此操作有 2 个选项:
- 使用类似于您共享的伪代码的动态元素。你可以有条件地选择元素,你只需要像这样使用标签的名称作为 string (免责声明:我不知道这是多么传统)
注意:组件的变量名称(在本例中为Component
)需要大写或使用点符号访问。 <Component />
或 <someObject.component />
会起作用,但 <component />
不会。
function Item({prop}) {
const Component = prop ? 'h1' : 'h6'
return <Component>
<div>It works!</div>
</Component>
}
此解决方案也适用于自定义反应组件而不是 HTML 标签。看起来像这样
function FuncComponent() {}
function OtherComponent() {}
function Item({prop}) {
const Component = prop ? FuncComponent : OtherComponent
return <Component>
<div>It works!</div>
</Component>
}
- 首先在
return
语句之前渲染子元素,然后将其作为子元素提供给您想要的元素
function Item({prop}) {
const children = <div>It works!</div>
return {prop ? <h1>{children}</h1> : <h6>{children}</h6>}
}
这些都行,就看你喜欢哪个了。