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

React中如何跨两级组件传递带ID参数的handleClick函数?

React跨两级组件传递带参数回调的修复方案

核心问题总结

需要将顶层App组件的handleClick回调向下传递两级(到Main再到动态渲染的Answer),实现点击Answer时把对应的answerId传回App以更新状态。现有代码的两个关键错误导致无法实现该功能:

  • App传递给Main的handleClick未正确关联顶层回调,且未预留参数传递入口
  • Main组件中调用的handleClick不是App传入的props回调,而是未定义的函数

修正后的完整代码

App组件

import { useState } from 'react';
import Main from './Main';

function App() {
  const [triviaData, setTriviaData] = useState([]); // 从API获取试题数据

  // 顶层回调:接收answerId并更新状态
  function handleClick(answerId) {
    console.log('点击的选项ID:', answerId);
    // 示例状态更新逻辑:切换对应选项的isClicked状态
    setTriviaData(prevData => 
      prevData.map(question => ({
        ...question,
        answers: question.answers.map(answer => 
          answer.answerId === answerId 
            ? {...answer, isClicked: !answer.isClicked} 
            : answer
        )
      }))
    );
  }

  const triviaElements = triviaData.map(item => (
    <Main 
      item={item} 
      key={item.id} 
      handleClick={handleClick} // 直接传递顶层回调,无需提前绑定参数
    />
  ));

  return (
    <div>{triviaElements}</div>
  );
}

export default App;

Main组件

import Answer from './Answer';

export default function Main(props) {
  const triviaAnswers = props.item.answers.map(item => (
    <Answer 
      key={item.answerId} 
      answer={item.answer} 
      isCorrect={item.isCorrect} 
      answerId={item.answerId} 
      // 使用App传入的回调,绑定当前选项的answerId
      handleClick={() => props.handleClick(item.answerId)} 
    />
  ));

  return( 
    <section className="main">
      <h2 className="main--question">{props.item.question}</h2>
      {triviaAnswers}
    </section> 
  );
}

Answer组件(无需修改)

export default function Answer(props) { 
  return ( 
    <div className="answer" onClick={props.handleClick}>{props.answer}</div>
  );
}

可选优化:用useCallback减少不必要重渲染

如果triviaData频繁更新,每次渲染App时都会创建新的handleClick函数,导致Main和Answer组件重复渲染。可以用useCallback缓存回调函数:

import { useState, useCallback } from 'react';

// ...

const handleClick = useCallback((answerId) => {
  console.log('点击的选项ID:', answerId);
  setTriviaData(prevData => 
    prevData.map(question => ({
      ...question,
      answers: question.answers.map(answer => 
        answer.answerId === answerId 
          ? {...answer, isClicked: !answer.isClicked} 
          : answer
      )
    }))
  );
}, []); // 依赖项为空,因为setTriviaData是useState返回的稳定函数

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 12:25:24