React 组件子项在渲染前检测是否为空/空

IT技术 javascript reactjs
2021-05-25 02:18:04

“react”:“16.8.4”

你好,有人知道如何检查(功能)组件中是否存在子组件(在渲染它们之前)

React.Children.count
React.Children.toArray(children)

行不通

孩子们是 $$typeof: Symbol(react.element)

代码示例是

function ContextMenuItems(): JSX.Element | null {
   if (no-items) return null;  
   ...
}

class ContextMenu extends React.Component {
   public render(): JSX.Element | null {
      if (this.props.children === null) { //ContextMenuItems empty check
        return null;
       }
       return <ContextMenu>{this.props.children}</ContextMenu>
   }
}

对于任何帮助,想法谢谢

4个回答

解决方案1:

得到孩子typenull如果Child组件返回 null ,它将返回

const isChildNull = children => {
  return Boolean(children.type()=== null);
};

解决方案2:

使用ReactDOMServer.renderToStaticMarkup它将jsx元素转换string. 如果 children 返回 null 那么renderToStaticMarkup将返回一个空字符串:

import ReactDOMServer from 'react-dom/server';

const isChildNull = children => {
  return !Boolean(ReactDOMServer.renderToStaticMarkup(children));
};

用法:

const Child = () => {
  return null;
};
    
const Parent = ({ children }) => {
  const isNull = isChildNull(children);
  if (isNull) {
     return "render null";
  }
  return <div>{children}</div>;
};
    
export default function App() {
   return (
     <Parent>
        <Child />
     </Parent>
   );
}

使用解决方案 1 的工作示例

您可以通过阅读 children props和React.Children.count来检查组件是否有子组件,代码将是:

function ContextMenuItems({ children }): JSX.Element | null {
   if (!React.Children.count(children)) return null;
   ...
}

您可以在应用 React.Children.count 之前添加isValidElement检查作为

function getValidChildren(children) {
  return React.Children.toArray(children).filter((child) =>
    React.isValidElement(child)
  ) as React.ReactElement[]
}

function ContextMenuItems({ children }): JSX.Element | null {
   if (!React.Children.count(getValidChildren(children))) return null;
   ...
}

除了其他解决方案,如果您想检查子项是否为空字符串,您可以执行以下测试:

!React.isValidElement(children) && children === ""

它帮助我做了一个帮助组件,如果作为子组件提供的组件是空字符串,它可以编写文本:

const EmptyTextHelper = ({ children }: { children?: React.ReactNode }) => !React.isValidElement(children) && children === "" ? (
<span className="italic">No text</span>) : (
<>{children}</>);