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

React父组件API获取数据更新后子组件未重渲染白屏问题

问题原因
  • 白屏崩溃:首次渲染时父组件传入的user初始值是空对象{},本身不存在includes数组方法,直接调用user.includes()会抛出类型错误;同时你写的user.includes(user?.id)逻辑本身有误,includes只能在数组实例上调用,普通对象调用该方法必然报错。
  • 子组件不更新:useState的初始化逻辑仅在组件首次挂载时执行1次,后续父组件props更新传入新的user值时,子组件内部的followed状态不会自动同步。你写的useEffect虽然依赖了user,但内部没有任何状态更新逻辑,自然不会触发视图重渲染。
  • 额外语法问题:父组件中渲染子组件时使用了小写标签<child />,React会将小写开头的标签识别为原生DOM节点,不会渲染你导入的Rightbar组件,也会导致异常。
修复步骤

1. 修正父组件逻辑

将user初始值设为null区分加载状态,接口返回数据前不渲染子组件,避免传入无效初始值;同时修正子组件标签名为大写开头的正确组件名。

export default function Profile() {
  // 初始值设为null,标记未加载状态
  const [user, setUser] = useState(null);
  const PF = process.env.REACT_APP_PUBLIC_FOLDER;
  const username = useParams().username;

  useEffect(() => {
    const fetchUser = async () => {
      try {
        const res = await axios.get(
          `http://localhost:8000/api/users?username=` + username
        );
        setUser(res.data);
      } catch (e) {
        console.log(e);
      }
    };
    fetchUser();
  }, [username]);

  // 数据加载中展示占位内容,不渲染子组件
  if (!user) return <div>加载中</div>

  return <>
    {/* 自定义组件必须大写开头 */}
    <Rightbar user={user} />
  </>
}

2. 修正子组件逻辑

首先明确业务逻辑:includes只能用于判断某个值是否存在于数组中,你需要找到实际存储关注ID列表的数组字段(通常是当前登录用户的followings数组)再做判断,不要直接在user对象上调用该方法。
两种可选修复方案:

方案1:保留本地状态,监听props同步更新

适合需要在子组件内部修改followed状态的场景(比如点击关注/取关按钮后直接更新状态)

export default function Rightbar({ user, currentUser }) {
  // 初始化时做好类型校验,避免非法值报错
  const [followed, setFollowed] = useState(() => {
    if (!user?.id || !Array.isArray(currentUser?.followings)) return false;
    return currentUser.followings.includes(user.id);
  });

  // 监听依赖项变化,同步更新状态
  useEffect(() => {
    if (!user?.id || !Array.isArray(currentUser?.followings)) {
      setFollowed(false);
      return;
    }
    setFollowed(currentUser.followings.includes(user.id));
  }, [user, currentUser]);

  return (
    // 组件业务代码
  )
}

方案2:直接使用派生值,省去同步逻辑

如果followed不需要在子组件内部独立修改,完全由props计算得到,推荐用这种写法,避免状态不同步的bug

export default function Rightbar({ user, currentUser }) {
  // 直接根据props计算结果,props变化时自动更新
  const followed = !!(
    user?.id 
    && Array.isArray(currentUser?.followings) 
    && currentUser.followings.includes(user.id)
  );

  return (
    // 组件业务代码
  )
}

注意:上述代码中的currentUser为当前登录用户对象,你需要替换为项目中实际存储登录用户信息的变量。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 04:12:21