You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何仅当UserInfo组件返回非空值时渲染‘by <UserInfo />’部分?

要实现仅当 <UserInfo /> 返回非空内容时才渲染 by <UserInfo /> 这部分,我们可以结合组件逻辑和 React 的条件渲染来解决,这里有几个实用的方案:

方案1:提取自定义Hook复用用户信息逻辑

首先把 <UserInfo /> 里的用户信息获取逻辑抽成一个自定义Hook,这样父组件和子组件能共享逻辑,避免重复发起API请求:

// 自定义Hook:useUserInfo.js
export const useUserInfo = (userId) => {
  const { useGet } = useApi();
  const { data: userInfo } = useGet(`/users/${userId}`);
  
  if (!userInfo?.data?.displayName) {
    return null;
  }
  
  const [lastName, firstName] = userInfo.data.displayName.split(',') || [];
  return firstName && lastName ? `${firstName} ${lastName}` : userInfo.data.displayName;
};

修改 <UserInfo /> 组件使用这个Hook:

// UserInfo.js
import { useUserInfo } from './useUserInfo';

export default function UserInfo({ userId }) {   
    const userName = useUserInfo(userId);
    return userName ? <span>{userName}</span> : null;
}

最后在父组件里,直接拿到 userName 状态做条件渲染:

<Typography>
  Updated {item.updatedAt} ago
  {userName && (
    <>
      , by{' '}
      <UserInfo userId={item.updatedBy} />
    </>
  )}
</Typography>

方案2:给<UserInfo />添加Render Props

如果不想抽离Hook,也可以给 <UserInfo /> 加上render props,让父组件完全控制带前缀的渲染逻辑:

修改 <UserInfo /> 组件:

export default function UserInfo({ userId, render }) {   
    const { useGet } = useApi()
    const { data: userInfo } = useGet(`/users/${userId}`)
    const [lastName, firstName] = userInfo?.data.displayName?.split(',') || []
    const userName = firstName && lastName ? `${firstName} ${lastName}` : userInfo?.data.displayName    
  
    // 没有用户名时直接返回null
    if (!userName) {
      return null;
    }
  
    // 有render函数则调用它传入用户名,否则默认渲染span
    return render ? render(userName) : <span>{userName}</span>;
}

父组件这样使用:

<Typography>
  Updated {item.updatedAt} ago
  <UserInfo 
    userId={item.updatedBy} 
    render={(userName) => `, by ${userName}`} 
  />
</Typography>

方案3:无修改的条件渲染(避免重复请求)

如果不想改动 <UserInfo /> 的结构,先确保组件在无内容时返回null(修改原组件的return部分):

// 修改UserInfo的return语句
return userName ? <span>{userName}</span> : null;

然后在父组件里用useMemo缓存组件实例,再判断是否渲染前缀:

import { useMemo } from 'react';

// ...

const userInfoElement = useMemo(() => (
  <UserInfo userId={item.updatedBy} />
), [item.updatedBy]);

<Typography>
  Updated {item.updatedAt} ago
  {userInfoElement && (
    <>
      , by{' '}
      {userInfoElement}
    </>
  )}
</Typography>

关键注意点

  • 必须让 <UserInfo /> 在userName为空时返回null,而不是空<span></span>——因为React元素对象永远是truthy值,空span会导致条件判断失效。
  • 异步请求加载完成前,userName会是null,此时"by"部分不会渲染;等数据加载完成后,若userName有效才会自动显示。

内容的提问来源于stack exchange,提问作者user3378165

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 16:15:57