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

React/TypeScript开发中点击一个元素如何触发另一元素的对应函数

解决方案

核心思路是把投票后的胜负更新逻辑抽到父组件Game中处理,因为父组件持有当前对战的两只仓鼠的完整数据,可以轻松区分获胜方和战败方,分别触发对应的更新方法。

具体改动步骤

  1. 在Game组件中新增投票处理函数,接收获胜仓鼠的id,分别查找胜负双方,批量更新数据后刷新对战
  2. 调整传给FighterCard的props,把投票处理函数传给子组件,替代原来的updateWin
  3. 修改FighterCard内部的点击逻辑,点击仓鼠时调用传入的投票函数,把当前仓鼠的id回传给父组件

修改后的完整代码

import { useEffect, useState } from 'react';
import { Hamster } from '../../models/Hamster';
import FighterCard from './FighterCard'
import '../../styles/game.css'

type Hamsters = Hamster;

const baseUrl = 'http://localhost:1337';

const Game = () => {

    const [fighters, setFighters] = useState<Hamsters[] | null>(null)
    

    useEffect(() => {
        getFighters(setFighters)
    }, [])

    function newGame() {
        getFighters(setFighters)
    }


    function updateWin(id: string, wins: number, games: number) {
        const newWins = wins + 1;
        const newGames = games + 1;

        return fetch(baseUrl + '/hamsters/' + id, {
        method: 'PUT',
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({wins: newWins, games: newGames})
        })
        
    }

    function updateDefeats(id:string, defeats: number, games: number) {
        const newDefeats = defeats + 1;
        const newGames = games + 1;

        return fetch(baseUrl + '/hamsters/' + id, {
        method: 'PUT',
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({defeats: newDefeats, games: newGames})
        })
        
    }

    // 新增投票处理函数
    async function handleVote(winnerId: string) {
      if (!fighters) return
      const winner = fighters.find(item => item.id === winnerId)!
      const loser = fighters.find(item => item.id !== winnerId)!
      try {
        // 等待胜场、败场两个更新请求都完成
        await Promise.all([
          updateWin(winner.id, winner.wins, winner.games),
          updateDefeats(loser.id, loser.defeats, loser.games)
        ])
        // 更新完成后自动开启新对战
        newGame()
      } catch (e) {
        console.error('对战数据更新失败:', e)
      }
    }
    

    return (
        <div className='game'>
            <h2>Let the fight begin!</h2>
            <p>Click on the cutest hamster</p>

            <section className="fighters">
                {fighters
                ? fighters.map(fighter => (
                    {/* 把handleVote传给子组件 */}
                    <FighterCard fighter={fighter} key={fighter.id} onVote={handleVote}/>
                ))
                : 'Loading fighters...'}
            </section>

            <button onClick={newGame}>New Game</button>

        </div>
    )
};



async function getFighters(saveFighters: any) {
    const response = await fetch(baseUrl + '/hamsters');
    const data = await response.json()
    const fighters = data.sort(() => .5 - Math.random()).slice(0,2)
    saveFighters(fighters)
};

export default Game 

FighterCard组件适配改动

在FighterCard组件中,将原来点击仓鼠时调用updateWin的逻辑,改为调用传入的onVote方法,传入当前仓鼠的id即可,示例:

// FighterCard.tsx 内部点击逻辑示例
const FighterCard = ({ fighter, onVote }) => {
  return (
    <div onClick={() => onVote(fighter.id)}>
      {/* 原有卡片渲染逻辑 */}
    </div>
  )
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 23:36:08