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
相关产品推荐
相关产品推荐

