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

React点击SHOW按钮无法正确展示指定用户博客列表的问题

问题描述

我的React应用展示用户列表,每个用户有若干博客(含标题、作者、URL)。当前用户列表显示格式如下:

User 1 : blogs: 2 SHOW

User 2 : blogs: 8 SHOW

……

点击SHOW按钮本应渲染对应用户的博客详情,示例如下:

User 1's blogs:

Title1
Title2
……

但实际问题是:无论点击哪个用户的SHOW按钮,页面始终只展示User 1的博客详情。怀疑问题出在handleClick函数中,相关代码如下:

原组件代码

import userService from '../services/users'
import { useState, useEffect } from 'react'

const User = () => {
  const [users, setUsers] = useState([])
       
  const handleClick = () => {
      users.map(u => setUsers([u]))
  }
  
  useEffect(() => {
      userService
        .getAll()
        .then(users => {
          setUsers(users)
        })
    }, [])
  
  console.log(users)
  
  const blogStyle = {
    paddingTop: 10,
    paddingLeft: 2,
    border: "solid",
    borderWidth: 1,
    marginBottom: 5,
  };
  
  if (!users) {
    return null
  }
  
  if (users.length === 1) {
    return (
        <div>
            <h2>{users.map(u => u.username)}'s entries</h2>
            {users.map(u => u.blogs.map(u => <li key={u.id} style={blogStyle}>{u.title}</li>))}
        </div>
    )
  }
  
  return (
      <div>
          <h2>Users</h2>
          <ul>
              {users.map(u => <li key={u.id} style={blogStyle}>{u.username}: {u.blogs.length}<button onClick={handleClick}>Show</button></li>)}
          </ul>
      </div>
  )
}

export default User

服务代码

import axios from "axios";
const baseUrl = "/api/users";

const getAll = () => {
    const request = axios.get(baseUrl);
    return request.then((response) => response.data);
};

export default { getAll }

用户数据

[{"title":"Blog Title","author":"J John","url":"www.url.com","id":"628f998a532016f769978e95","likes":0},{"title":"Blog Title","author":"J John","url":"www.url.com","user":{"username":"root","name":"Superuser","id":"628f969252b604bdb13b672e"},"id":"628f9b685bfa95ded0cb29cf","likes":0},{"title":"Blog Title","author":"J John","url":"www.url.com","user":{"username":"root","name":"Superuser","id":"628f969252b604bdb13b672e"},"id":"6298ba4da20133b892443f75","likes":0},{"title":"Passwords and tokens","author":"I Fleming","url":"www.iiii.com","user":{"username":"testuser","name":"testuser","id":"6298bef3c00dbef70a9f3c55"},"id":"6298cc365935ee8f873dd2cf","likes":0},{"title":"jjj","author":"jjj","url":"jjj","user":{"username":"jjj","name":"jjj","id":"629b18d3272af122ea7830f2"},"id":"629b194c5ad19d29b2d30910","likes":0},{"title":"You","author":"Program","url":"www.kkk.com","user":{"username":"kkk","name":"kkk","id":"629b19b15ad19d29b2d30915"},"id":"629b1a1e5ad19d29b2d3091d","likes":0},{"title":"Zoom","author":"Parzifal","url":"www.smorg.com","user":{"username":"kkk","name":"kkk","id":"629b19b15ad19d29b2d30915"},"likes":1,"id":"629b1b5fd8d110a6e5d4671e"},{"title":"Rank ","author":"J John","url":"www.rank.com","user":{"username":"mmm","name":"mmm","id":"629b5b62d2afb19a39515c77"},"id":"629f53295cfed3eca2683add","likes":0},{"title":"Test Title With Update","author":"J John","url":"www.title.com","user":{"username":"mmm","name":"mmm","id":"629b5b62d2afb19a39515c77"},"likes":3,"id":"62cc19b6df95af90c24418df"},{"title":"fdddd","author":"Daniel Harmann","url":"Daniel Harmann","user":{"username":"mmm","name":"mmm","id":"629b5b62d2afb19a39515c77"},"id":"62d1760131423c5391b17a91","likes":0}]
问题原因

当前handleClick函数逻辑完全错误:它遍历所有用户并连续调用setUsers([u]),React会批量处理这些状态更新,最终users数组会被设置为遍历最后一步的用户(因数据顺序或批量更新机制,导致始终显示User1)。同时用users数组同时存储完整列表和选中用户,状态逻辑混乱。

解决方案

新增单独状态记录选中用户,不修改原始用户列表(始终保存完整数据)。具体修改如下:

修改后的组件代码
import userService from '../services/users'
import { useState, useEffect } from 'react'

const User = () => {
  const [users, setUsers] = useState([])
  // 新增状态:存储当前选中的用户
  const [selectedUser, setSelectedUser] = useState(null)
       
  // 修改handleClick,接收当前点击的用户作为参数
  const handleClick = (user) => {
    setSelectedUser(user)
  }

  // 新增返回列表的函数
  const handleBack = () => {
    setSelectedUser(null)
  }
  
  useEffect(() => {
    userService
      .getAll()
      .then(users => {
        setUsers(users)
      })
  }, [])
  
  const blogStyle = {
    paddingTop: 10,
    paddingLeft: 2,
    border: "solid",
    borderWidth: 1,
    marginBottom: 5,
  };
  
  // 优化加载状态判断
  if (!users.length) {
    return <div>Loading...</div>
  }
  
  // 显示选中用户的博客详情
  if (selectedUser) {
    return (
      <div>
        <button onClick={handleBack}>Back to users</button>
        <h2>{selectedUser.username}'s entries</h2>
        <ul>
          {selectedUser.blogs.map(blog => (
            <li key={blog.id} style={blogStyle}>
              {blog.title} - {blog.author}
            </li>
          ))}
        </ul>
      </div>
    )
  }
  
  // 显示完整用户列表
  return (
    <div>
      <h2>Users</h2>
      <ul>
        {users.map(user => (
          <li key={user.id} style={blogStyle}>
            {user.username}: {user.blogs.length}
            <button onClick={() => handleClick(user)}>Show</button>
          </li>
        ))}
      </ul>
    </div>
  )
}

export default User
关键修改说明
  • 用selectedUser单独存储选中用户,避免覆盖原始列表,状态逻辑更清晰
  • handleClick接收点击的用户参数,精准设置选中状态
  • 新增返回按钮,支持从详情页回到列表页
  • 优化加载状态判断,!users.length比!users更准确(初始状态是空数组而非null)
  • 嵌套map改用不同变量名(user/blog),避免变量冲突,提升可读性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 21:54:18