如何仅当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
相关产品推荐
相关产品推荐

