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

React JS中如何给onClick处理函数传递变量作为参数?

问题描述

我正在尝试创建一个React应用,用于展示我用React实现的基础项目列表。预期效果是:点击「Click me」按钮时,将当前显示的默认组件替换为data数组中对应的React项目组件,初始实现代码如下:

import React, { useState } from "react";
import Birthday from "./Birthday_src/Birthday";
import Tours from "./Tours_src/App";

const data = [
  {
    id: 1,
    btn: <Birthday />,
  },
  {
    id: 2,
    btn: <Tours />,
  },
];
export default function Container() {
  const [project, setProject] = useState(Default);

  function Default() {
    return (
      <>
        <div className="container">
          <h1>15 Basic React Projects. </h1>
          <p>that are based on react...(obviously) </p>

          <div className="row row-cols-3 mt-10 mx-3 ">

            {data.map((cProject, index) => {
              const { id, btnP } = cProject;
            

              return (
                <div className="items" key={id}>

                  <p>Here goes the first project. </p>
                  <button
                    className="btn-primary btn"
                    id={`btn${id}`}
                    onClick={(e,btnP) => {
                      console.log(e.target.id);
                      console.log(btnP)
                      setProject(btnP);
                    }}
                  >
                    Click me
                  </button>
                </div>
              );
            })}
          </div>
        </div>
      </>
    );
  }

  return <>{project}</>;
}

实际运行时点击按钮,e.target.id可以正常在控制台打印对应id值,但btnP始终显示为undefined,需要实现点击对应按钮时渲染匹配的React项目组件的效果。

问题根因

你的代码有三处核心错误:

  • data数组里存储组件的字段名是btn,但解构时写的是btnP,字段名不匹配,解构出来的值本身就是undefined
  • React的onClick事件回调默认只会传入事件对象e这一个参数,你在回调形参里定义的第二个参数btnP无法接收到外部遍历的变量,永远是undefined
  • 不要把用于渲染的组件定义在另一个函数组件内部,每次父组件重渲染都会重新生成该组件的引用,会导致不必要的重渲染甚至子组件状态丢失。
修复方案

直接在map遍历的作用域里捕获当前项的组件值,点击时直接传入setProject即可;默认展示的首页组件抽离到父组件外部定义,避免重复创建引用,修正后的代码如下:

import React, { useState } from "react";
import Birthday from "./Birthday_src/Birthday";
import Tours from "./Tours_src/App";

const data = [
  {
    id: 1,
    component: <Birthday />,
  },
  {
    id: 2,
    component: <Tours />,
  },
];

// 默认展示的项目列表首页
function DefaultView({ onSelectProject }) {
  return (
    <div className="container">
      <h1>15 Basic React Projects. </h1>
      <p>that are based on react...(obviously) </p>

      <div className="row row-cols-3 mt-10 mx-3 ">
        {data.map((cProject) => {
          const { id, component } = cProject;
          return (
            <div className="items" key={id}>
              <p>Project {id}</p>
              <button
                className="btn-primary btn"
                id={`btn${id}`}
                onClick={() => {
                  // 直接传入当前遍历项的组件即可
                  onSelectProject(component);
                }}
              >
                Click me
              </button>
            </div>
          );
        })}
      </div>
    </div>
  );
}

export default function Container() {
  // 初始状态渲染默认首页,传入切换项目的方法
  const [project, setProject] = useState(<DefaultView onSelectProject={setProject} />);

  return <>{project}</>;
}

小提示:如果不想修改原有data数组的字段名,只需要把解构语句改成const { id, btn: component } = cProject即可,效果完全一致。如果后续需要从项目页返回首页,只需要在对应项目组件内加返回按钮,点击时调用setProject(<DefaultView onSelectProject={setProject} />)就能切回列表页。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 18:16:01