React函数式组件map渲染触发display name缺失报错
报错原因
ESLint的react/display-name规则会自动识别返回JSX结构的函数为React函数式组件,你代码里双层柯里化箭头函数的最内层(card, i) => { return <div>...</div> }属于匿名函数,规则无法自动推断出它的组件显示名,就会抛出该错误。本质上这个内层函数是Array.map的渲染回调,并不是真正需要复用的独立组件,属于规则误判。
修复方案
方案1:调整为普通渲染回调写法(推荐)
去掉多余的函数嵌套层级,避免返回JSX的函数被规则识别为独立组件,同时也能避免嵌套组件定义带来的子组件重复重挂载问题。const Sales = (props: Props) => { const renderCard = React.useMemo( (config, card, i) => { return ( <div {...config} key={i}> <Card Icon={card.Icon} label={card.label} /> </div> ); }, [cards] ); return ( <div title="Sales"> <div> {cards.slice(0, 3).map((card, i) => renderCard(configOne, card, i))} </div> {/* 其他业务逻辑 */} <div> {cards.slice(3).map((card, i) => renderCard(configTwo, card, i))} </div> </div> ); };方案2:显式指定内层函数的displayName
如果要保留原有柯里化的调用写法,可以给内层返回JSX的函数命名并手动绑定displayName,满足规则校验要求:const Sales = (props: Props) => { const renderCard = React.useMemo( () => (config) => { const CardWrapper = (card, i) => { return ( <div {...config} key={i}> <Card Icon={card.Icon} label={card.label} /> </div> ); }; CardWrapper.displayName = 'CardWrapper'; return CardWrapper; }, [cards] ); return ( <div title="Sales"> <div> {cards.slice(0, 3).map(renderCard(configOne))} </div> {/* 其他业务逻辑 */} <div> {cards.slice(3).map(renderCard(configTwo))} </div> </div> ); };方案3:针对误报行临时禁用规则
如果确认当前写法不会带来性能问题,可在触发报错的代码行上方添加单行禁用注释,跳过该行的规则校验:const renderCard = React.useMemo( () => (config) => // eslint-disable-next-line react/display-name (card, i) => { return ( <div {...config} key={i}> <Card Icon={card.Icon} label={card.label} /> </div> ); }, [cards] );注意:不要全局关闭
react/display-name规则,否则会漏掉真正的匿名组件问题,增加调试难度。
注意:不要在渲染逻辑里定义匿名嵌套组件,每次渲染都会重新生成新的组件引用,会导致子组件状态丢失、不必要的重挂载,优先选择方案1的写法最稳妥。
内容的提问来源于stack exchange,提问作者Forgotten-Storm
相关产品推荐
相关产品推荐

