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

ReactJS中点击按钮切换渲染不同视图的实现求助

解决方案:React中点击按钮渲染单场比赛详情组件

看你的代码已经有了核心逻辑的雏形,不过有几个细节问题需要修正,同时我们可以优化交互体验,让功能更完整。下面是具体的改进方案:

1. 先修正核心错误

你的代码里有两个关键问题导致功能无法正常工作:

  • Matchinfo组件接收的props参数名不匹配:Content里传的是matchid,但Matchinfo里用了match_id,这会导致请求URL错误
  • 已废弃的生命周期:componentWillMount已经被React弃用,应该用componentDidMount发起请求

2. 优化后的完整代码

Content组件

import React, { Component } from 'react';
import Matchinfo from './matchinfo';
import './content.css';

class Content extends Component {
  constructor(props){
    super(props);
    this.state = {
      matches:[],
      loading:true,
      callmatchinfo: false,
      matchid:''
    };
    // 绑定this,避免函数调用时丢失上下文
    this.viewstats = this.viewstats.bind(this);
    this.closeMatchDetail = this.closeMatchDetail.bind(this);
  }

  componentDidMount(){
    fetch('api/matches')
      .then(res => res.json())
      .then(res => {
        console.log(res)
        this.setState({ matches:res.slice(0,16), loading:false });
      })
      .catch(err => console.error('获取比赛列表失败:', err)) // 添加错误捕获
  }

  viewstats(matchid){
    this.setState({ callmatchinfo: true, matchid: matchid });
  }

  closeMatchDetail() {
    this.setState({ callmatchinfo: false, matchid: '' });
  }

  renderMatchInfo(){
    // 传递关闭函数给子组件
    return <Matchinfo matchid={this.state.matchid} onClose={this.closeMatchDetail} />
  }

  renderMatches() {
    return this.state.matches.map(match => {
      return (
        // 列表渲染必须添加唯一key属性
        <div className="col-lg-3" key={match.id}>
          <div id="content">
            <p className="match">MATCH {match.id}</p>
            <h4>{match.team1}</h4>
            <p>VS</p>
            <h4>{match.team2}</h4>
            <div className="winner">
              <h3>WINNER</h3>
              <h4>{match.winner}</h4>
            </div>
            <div className="stats">
              <button type="button" onClick={() => this.viewstats(match.id)} className="btn btn-success">View Stats</button>
            </div>
          </div>
        </div>
      );
    })
  }

  render() {
    if (this.state.loading) {
      return <img src="https://upload.wikimedia.org/wikipedia/commons/b/b1/Loading_icon.gif" alt="加载中"/>
    }
    return (
      <div>
        <div className="row">
          {this.renderMatches()}
        </div>
        <div className="row">
          {/* 用&&替代三元表达式,更简洁的条件渲染 */}
          {this.state.callmatchinfo && this.renderMatchInfo()}
        </div>
      </div>
    );
  }
}

export default Content;

Matchinfo组件

import React, { Component } from 'react';

class Matchinfo extends Component {
  constructor(props){
    super(props);
    this.state = {
      info:{}, // 改成对象更合理,因为单场比赛是单个数据而非数组
      loading:true
    };
  }

  componentDidMount(){
    // 使用正确的props参数名matchid
    this.fetchMatchDetail(this.props.matchid);
  }

  // 当切换不同比赛时,重新获取数据
  componentDidUpdate(prevProps){
    if (prevProps.matchid !== this.props.matchid) {
      this.setState({ loading: true });
      this.fetchMatchDetail(this.props.matchid);
    }
  }

  fetchMatchDetail(matchid) {
    fetch(`api/match/${matchid}`)
      .then(res => {
        if (!res.ok) throw new Error('请求失败'); // 检查响应状态
        return res.json();
      })
      .then(res => {
        console.log(res)
        this.setState({ info:res, loading:false })
      })
      .catch(err => console.error('获取比赛详情失败:', err))
  }

  render() {
    if (this.state.loading) {
      return <img src="https://upload.wikimedia.org/wikipedia/commons/b/b1/Loading_icon.gif" alt="加载中"/>
    }
    const {info} = this.state;
    return (
      <div className="match-detail-container">
        {/* 添加关闭按钮,提升交互体验 */}
        <button type="button" onClick={this.props.onClose} className="btn btn-secondary mb-3">关闭详情</button>
        <p className="match">MATCH {info.id}</p>
        <h4>{info.team1}</h4>
        <p>VS</p>
        <h4>{info.team2}</h4>
        <div className="winner">
          <h3>WINNER</h3>
          <h4>{info.winner}</h4>
        </div>
        {/* 这里可以扩展更多详情内容,比如球员数据、比分变化等 */}
      </div>
    );
  }
}

export default Matchinfo;

关键改进说明

  • key属性:列表渲染必须添加唯一key,帮助React高效更新DOM
  • props参数匹配:确保父子组件的参数名一致,避免请求错误
  • 生命周期优化:用componentDidMount发起初始请求,componentDidUpdate处理切换比赛时的重新请求
  • 错误处理:添加fetch的错误捕获,方便调试网络问题
  • 交互优化:增加关闭详情按钮,让用户可以回到比赛列表
  • 代码简洁性:用&&替代冗余的三元表达式,符合React最佳实践

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:40:29