有没有办法判断 ReactElement 是否呈现“null”?

IT技术 javascript reactjs react-jsx
2021-05-03 12:39:12

在我的 JSX 中,我有一个条件渲染逻辑的情况 - 当元素 A 渲染某些内容时(它的render()函数返回的不是null),然后还渲染元素 B,就在元素 A 的上方。

代码示例(简化)如下所示:

function render() {
    let elemA = (<ElementA someProp={this.someVar} />);

    if (elemA.isNull()) {
        return (
            <div>
                { ...someElements }
            </div>
        );
    }

    return (
        <div>
            { ...someElements }
            <ElementB />
            { elemA }
        </div>
    );
}

所以我的问题是- 有什么办法可以得到elemA.isNull()支票吗?

4个回答

不,没有办法确定孩子将使用 React 呈现什么。执行此操作的标准方法是公开一些实用程序函数,说明 A 是否会呈现。

就像是:

if (AUtils.isStoryValid(story)) {
  return <A story={story} />;
} else {
  return <B story={story} />;
}

您可以使用以下高阶组件(HOC)来拦截ElementA的render方法并完成您想要的:

function withNullCheck(WrappedComponent) {
  return class NullChecker extends WrappedComponent {
    render() {
      const result = super.render();
      return(
        <div>
          { this.props.alwaysPrefix }
          { result && this.props.ifNotNullPrefix }
          { result ? result : this.props.ifNull }
          { result && this.props.ifNotNullAppend }
          { this.props.alwaysAppend }
        </div>  
      );
    }
  }
}

你会像这样使用它:

const NullCheckedElementA = withNullCheck(ElementA);

...

function render() {

    return ( 
      <NullCheckedElementA 
         alwaysPrefix={someElements} 
         ifNotNullPrefix={elemB} 
         someProp={this.someVar} 
      />
    );

}

请注意,如果您的 ReactElement 已被编写为功能组件,您可以像调用其他任何函数一样调用该函数并检查其响应。作为一个简单的例子,我有一个函数组件,它根据传入的 prop 返回不同的图标:

import React from "react";

import PersonIcon from "@material-ui/icons/Person";
import GroupIcon from "@material-ui/icons/People";

export default function EntityIcon({ entity }) {
  switch (entity) {
    case "people":
      return <PersonIcon />;
    case "groups":
      return <GroupIcon />;
    default:
      console.error(`entity: ${entity} doesn't have an associated icon`);
      return null;
  }
}

上述内容通常参考:

    <ListItemIcon>
      <EntityIcon entity={search.entity} />
    </ListItemIcon>

但如果需要,我可以做一些有条件的魔法:

  if (EntityIcon({ entity: item.entity })) {
    ... conditional magic
  }

search.entityitem.entity恰巧在我的用例对象数组的属性,但我希望你的想法。

如果您ElementA是功能组件,这将很容易在这种情况下,您可以像这样执行 smt:

    function render() {
    let ElemA = ElementA({ someProp:  this.someVar});

    if (ElemA === null) {
        return (
            <div>
                { ...someElements }
            </div>
        );
    }

    return (
        <div>
            { ...someElements }
            <ElementB />
            <ElemA />
        </div>
    );
}