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

React中如何实现点击数组元素后单独显示该元素?代码求助

解决React中点击列表项显示对应内容的问题

刚从jQuery转React确实会有点不适应,毕竟React是状态驱动而非直接操作DOM的思路。你的核心问题是没法追踪点击的是哪篇帖子,而且直接在onClick里调用函数(比如handleClick(this))会导致组件一渲染就执行这个函数,而不是点击时才执行。下面一步步帮你修正代码:

1. 调整状态结构

首先,我们需要在state里保存被选中的帖子ID(或者整个帖子对象),而不是只用一个clicked布尔值——布尔值只能告诉我们“是否处于详情页”,但没法区分是哪篇帖子。修改state:

this.state = {
  error: null,
  isLoaded: false,
  posts: [],
  selectedPostId: null // 新增:保存选中的帖子ID,null表示没选中
};

2. 修正点击事件处理

在onClick里,我们需要传递当前点击的帖子ID给处理函数。这里有两种常用方式:

  • 用箭头函数包裹,传递参数
  • 用bind绑定参数

推荐第一种,更直观。修改列表项的onClick:

<li key={"Post" + post.id} onClick={() => this.handleClick(post.id)} align="start">

然后更新handleClick函数,把选中的ID存入state:

handleClick(postId) {
  this.setState({ selectedPostId: postId });
}

3. 实现返回功能

返回按钮的作用就是清空selectedPostId,回到列表视图:

handleReturn() {
  this.setState({ selectedPostId: null });
}

(注意:React会自动根据state变化重新渲染,不需要手动调用this.render())

4. 调整渲染逻辑

根据selectedPostId来判断渲染列表还是单个帖子:

  • 如果selectedPostId不为null:找到对应的帖子并渲染详情,同时添加返回按钮
  • 否则:渲染所有帖子列表

修改render里的判断逻辑:

render() {
  const { error, isLoaded, posts, selectedPostId } = this.state;
  
  if (error) {
    return <div>Error in loading</div>;
  } else if (!isLoaded) {
    return <div>Loading ...</div>;
  } else if (selectedPostId !== null) {
    // 找到选中的帖子
    const selectedPost = posts.find(post => post.id === selectedPostId);
    return (
      <div className="selectedPostContainer">
        <button onClick={() => this.handleReturn()}>← 返回列表</button>
        <p className="title">User: {selectedPost.userId}<br/>{selectedPost.title}</p>
        <p className="body">Post ID: {selectedPost.id}</p>
        <br/>
        <p className="body">{selectedPost.body}</p>
      </div>
    );
  } else {
    return (
      <div className="postContainer">
        <ol className="item">
          {posts.map((post) => (
            <li key={"Post" + post.id} onClick={() => this.handleClick(post.id)} align="start">
              <div>
                <p className="title">{post.title}</p>
                <p className="body">{post.body}</p>
              </div>
            </li>
          ))}
        </ol>
      </div>
    );
  }
}

完整修改后的代码

import React, { Component } from 'react';
import './GetOnlinePosts.css';

class GetOnlinePosts extends Component {
  constructor(props) {
    super(props);
    this.state = {
      error: null,
      isLoaded: false,
      posts: [],
      selectedPostId: null // 保存选中的帖子ID
    };
    this.handleClick = this.handleClick.bind(this);
    this.handleReturn = this.handleReturn.bind(this); // 别忘了绑定这个函数
  }

  handleClick(postId) {
    this.setState({ selectedPostId: postId });
  }

  handleReturn() {
    this.setState({ selectedPostId: null });
  }

  componentDidMount() {
    fetch("https://jsonplaceholder.typicode.com/posts")
      .then(response => response.json())
      .then(
        (result) => {
          this.setState({
            isLoaded: true,
            posts: result
          });
        },
        (error) => {
          this.setState({
            isLoaded: true,
            error
          })
        },
      )
  }

  render() {
    const { error, isLoaded, posts, selectedPostId } = this.state;
    
    if (error) {
      return <div>Error in loading</div>;
    } else if (!isLoaded) {
      return <div>Loading ...</div>;
    } else if (selectedPostId !== null) {
      const selectedPost = posts.find(post => post.id === selectedPostId);
      return (
        <div className="selectedPostContainer">
          <button onClick={this.handleReturn}>← 返回列表</button>
          <p className="title">User: {selectedPost.userId}<br/>{selectedPost.title}</p>
          <p className="body">Post ID: {selectedPost.id}</p>
          <br/>
          <p className="body">{selectedPost.body}</p>
        </div>
      );
    } else {
      return (
        <div className="postContainer">
          <ol className="item">
            {posts.map((post) => (
              <li key={"Post" + post.id} onClick={() => this.handleClick(post.id)} align="start">
                <div>
                  <p className="title">{post.title}</p>
                  <p className="body">{post.body}</p>
                </div>
              </li>
            ))}
          </ol>
        </div>
      );
    }
  }
}

export default GetOnlinePosts;

关键思路说明

和jQuery直接找DOM元素不同,React的核心是状态决定视图:

  • 当你点击帖子时,我们把该帖子的ID存入state
  • React检测到state变化,自动重新渲染组件
  • 渲染时根据state里的selectedPostId来决定显示列表还是单个帖子

这样就完全不需要手动操作DOM啦,慢慢适应这种思路就会越来越顺手~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 21:32:59