React/TypeScript开发中点击一个元素如何触发另一元素的对应函数
解决方案
核心思路是把投票后的胜负更新逻辑抽到父组件Game中处理,因为父组件持有当前对战的两只仓鼠的完整数据,可以轻松区分获胜方和战败方,分别触发对应的更新方法。
具体改动步骤
- 在
Game组件中新增投票处理函数,接收获胜仓鼠的id,分别查找胜负双方,批量更新数据后刷新对战 - 调整传给
FighterCard的props,把投票处理函数传给子组件,替代原来的updateWin - 修改
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
相关产品推荐
相关产品推荐

