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

React渲染时读取user.albums.size报undefined错误如何解决

问题根因说明

这个问题确实和JS的传引用机制有关,但同时存在多个React用法错误共同导致报错:

  • 你在findAlbum中拿到的selectedUser是state.usersData中对应对象的引用,直接给引用加albums属性确实修改了原对象,但你没有调用setState更新usersData,React无法感知state发生了变化,不会触发重渲染。
  • fetch是异步操作,你把请求相册的逻辑放在了render方法中循环触发,首次渲染时相册请求还没有返回,user.albums还不存在,直接访问.size自然会报undefined错误。
  • 你在render中触发请求,请求返回后如果修改了state会再次触发render,形成死循环,会无限发送相册请求。
  • 接口返回的albums是普通数组,没有size属性,需要用数组的length属性获取长度。

修复方案

  1. 把相册请求逻辑移到用户列表获取成功之后触发,不要放在render中
  2. 拿到相册数据后用不可变方式更新usersData,通过setState触发重渲染
  3. 渲染时增加兜底判断,避免异步未返回时报错

修正后代码

import React, { Component } from 'react';
import { render } from 'react-dom';
import Details from './Details';
import './index.css';

class App extends Component {
  constructor() {
    super();
    this.state = {
      usersData: [],
      error: null,
      selectedUser: null,
    };
  }

  handleClick = (id) => {
    const selectedUser = this.state.usersData.find(user => user.id === id)
    this.setState(() => ({ selectedUser }))
  }

  findAlbum = async (userId) => {
    try {
      const response = await fetch(`https://jsonplaceholder.typicode.com/users/${userId}/albums`)
      return await response.json()
    } catch (err) {
      this.setState({ error: err.message })
      return []
    }
  }

  componentDidMount() {
    fetch('https://jsonplaceholder.typicode.com/users')
      .then(response => response.json())
      .then(async (users) => {
        // 批量获取所有用户的相册数据
        const usersWithAlbums = await Promise.all(users.map(async user => {
          const albums = await this.findAlbum(user.id)
          // 不可变方式返回新对象,不修改原对象
          return { ...user, albums }
        }))
        this.setState({ usersData: usersWithAlbums })
      })
      .catch(err => this.setState({ error: err.message }))
  }

  render() {
    const usersList = this.state.usersData.map(user => {
      return <li key={user.id} onClick={() => this.handleClick(user.id)}>
        {user.name} {user.username} {user.email} 
        {/* 加兜底判断,albums存在才显示长度 */}
        {user.albums ? ` 相册数量:${user.albums.length}` : ''}
      </li>
    })

    return (
      <>
        <div className="UserList">
          <h1>Users</h1>
          <ul>{usersList}</ul>
        </div>
        <Details user={this.state.selectedUser} />
      </>
    );
  }
}

render(<App />, document.getElementById('root'));

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 16:36:01