React中如何检测同级Tbody组件是否存在以动态控制对应thead显示
解决方案
方案1:封装独立表格区块组件(无需改造现有Tbody组件,零父组件逻辑侵入)
把thead和对应的一组tbody封装到TableSection组件内,组件内部自行判断子tbody是否存在有效渲染内容,父组件无需维护任何判断条件:
import React from 'react'; const TableSection = ({ thead, children }) => { // 过滤掉返回null的无效tbody const validTbodys = React.Children.toArray(children).filter(child => { // 执行函数组件逻辑拿到渲染结果,无额外生命周期开销 const renderedContent = typeof child.type === 'function' ? child.type(child.props) : child; return renderedContent !== null; }); if (validTbodys.length === 0) return null; return ( <> {thead} {validTbodys} </> ); };
父组件使用方式:
<table> <TableSection thead={<thead>head-1</thead>}> <TbodyComponentA /> <TbodyComponentB /> </TableSection> <TableSection thead={<thead>head-2</thead>}> <TbodyComponentC /> <TbodyComponentD /> </TableSection> {/* 新增分组直接加TableSection即可,父组件无需新增任何逻辑 */} </table>
适用场景:Tbody为无复杂副作用的纯函数组件,改造成本最低
方案2:新增静态判断方法(性能最优,可维护性最高)
给每个Tbody组件新增静态的shouldRender方法,把内部的渲染判断逻辑抽成静态方法,组件本身和外部都可以直接调用判断,无需执行渲染逻辑:
// 改造Tbody组件 const TbodyComponentA = (props) => { if (!TbodyComponentA.shouldRender(props)) return null; return <tbody>实际渲染内容</tbody>; }; // 静态判断方法,外部可直接调用,无任何渲染开销 TbodyComponentA.shouldRender = (props) => { // 原组件内部的渲染判断逻辑写在这里 return props.dataList.length > 0; };
改造TableSection的判断逻辑:
const TableSection = ({ thead, children }) => { const validTbodys = React.Children.toArray(children).filter(child => { return child.type.shouldRender?.(child.props) !== false; }); if (validTbodys.length === 0) return null; return ( <> {thead} {validTbodys} </> ); };
适用场景:可改造现有Tbody组件,性能最好,后续维护逻辑只需修改对应Tbody内部的静态方法即可
方案3:挂载回调监听(适合复杂组件场景,无侵入判断)
如果Tbody组件内部有复杂副作用、无法抽离判断逻辑,可以用ref回调监听组件实际挂载状态,判断是否展示thead:
const TableSection = ({ thead, children }) => { const [hasValidTbody, setHasValidTbody] = React.useState(false); const renderCount = React.useRef(0); const updateRenderCount = React.useCallback((isRendered) => { renderCount.current += isRendered ? 1 : -1; setHasValidTbody(renderCount.current > 0); }, []); // 给子组件注入监听回调 const wrappedChildren = React.Children.toArray(children).map(child => React.cloneElement(child, { onRenderStateChange: updateRenderCount }) ); return ( <> {hasValidTbody && thead} {wrappedChildren} </> ); }; // 改造Tbody组件,挂载/卸载时通知状态变化 const TbodyComponentA = ({ onRenderStateChange }) => { const shouldRender = /* 原内部判断逻辑 */ true; React.useEffect(() => { onRenderStateChange?.(shouldRender); return () => onRenderStateChange?.(false); }, [shouldRender, onRenderStateChange]); if (!shouldRender) return null; return <tbody>实际内容</tbody>; };
适用场景:Tbody组件逻辑复杂、改造代价高,仅会产生1次额外重渲染,性能可接受
内容的提问来源于stack exchange,提问作者Ray
相关产品推荐
相关产品推荐

