我可以创建条件来渲染 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 个选项:

  1. 使用类似于您共享的伪代码的动态元素。你可以有条件地选择元素,你只需要像这样使用标签的名称作为 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>
}
  1. 首先在 return 语句之前渲染子元素,然后将其作为子元素提供给您想要的元素
function Item({prop}) {
   const children = <div>It works!</div>

   return {prop ? <h1>{children}</h1> : <h6>{children}</h6>}
}

这些都行,就看你喜欢哪个了。