如何通过Widgets组件的OnClick事件更新React的Tablelist组件数据?
解决React组件点击切换数据源的问题
问题分析
你当前的两种方案都存在关键问题:
- 方案一失效原因:Home组件给第一个Widgets传了
onClick={tableToggle},但Widgets组件根本没接收这个onClickprops,点击Widget时自然不会触发状态更新。 - 方案二失效原因:Widgets内部的点击事件仅在控制台打印日志,没有修改Home组件中控制数据源的
activeTable状态。React是单向数据流,子组件无法直接修改父组件状态,必须通过父组件传递的回调函数实现。
修复方案
核心思路:由Home组件统一管理状态,给每个Widgets传递带参数的回调函数,点击Widget时通过回调更新父组件状态,进而切换Tablelist的数据源。
步骤1:修改Home组件
- 改造
tableToggle函数,让它接收一个参数(对应要切换的table标识) - 给所有Widgets组件传递
onClick回调,传入对应数据源的标识
修改后的Home组件代码:
import { useState } from "react"; import { tableData, data2, data3, data4, data5 } from "../../components/widgets/data"; // 假设你有对应其他Widget的数据源 const Home = () => { const [activeTable, setActiveTable] = useState("firstTable"); // 接收table标识参数,更新状态 const tableToggle = (tableKey) => { setActiveTable(tableKey); } return ( <div className="home"> <Sidebar /> <div className="home-container"> <Navbar /> <div className="widgets"> <Widgets type="assets" onClick={() => tableToggle("firstTable")}/> <Widgets type="liabilities" onClick={() => tableToggle("secondTable")}/> <Widgets type="fund bal/net positions" onClick={() => tableToggle("thirdTable")}/> <Widgets type="revenue" onClick={() => tableToggle("fourthTable")}/> <Widgets type="expenses" onClick={() => tableToggle("fifthTable")}/> </div> <div className="data-visual"> <div className="list-container"> <div className="list-title">Balance Sheet</div> {activeTable === "firstTable" && <Tablelist title={tableData}/>} {activeTable === "secondTable" && <Tablelist title={data2} />} {activeTable === "thirdTable" && <Tablelist title={data3} />} {activeTable === "fourthTable" && <Tablelist title={data4} />} {activeTable === "fifthTable" && <Tablelist title={data5} />} </div> <div className="data-container"> <Donut /> </div> </div> </div> </div> ) } export default Home;
步骤2:修改Widgets组件
- 接收父组件传递的
onClickprops - 将
onClick绑定到Widget的根div上
修改后的Widgets组件代码:
import ArrowDropUpOutlinedIcon from '@mui/icons-material/ArrowDropUpOutlined'; // 确保导入了图标 const Widgets = ({type, onClick}) => { let data; switch (type) { case "assets": data = { title: "ASSETS", amount: "17,336,942", isMoney: false, link: "See all", }; break; case "liabilities": data = { title: "LIABILITIES", amount: "867,109", isMoney: false, link: "see all", }; break; case "fund bal/net positions": data = { title: "FUND BAL/NET POSITION", amount: "35,279,811", isMoney: false, link: "See all", }; break; case "revenue": data = { title: "REVENUE", amount: "22,474,202", isMoney: false, link: "See all", }; break; case "expenses": data = { title: "EXPENSES", amount: "40,582,128", isMoney: false, link: "See all", }; break; default: break; } return ( <div className="widget" onClick={onClick}> <div className="left"> <span className="title">{data.title}</span> <span className="counter">${data.amount}</span> <span className="link">{data.link}</span> </div> <div className="right"> <div className="percentage"> <ArrowDropUpOutlinedIcon /> 50% </div> </div> </div> ) } export default Widgets;
补充说明
- 如果部分Widget不需要切换数据源,可以不传
onClick,或者传递空函数() => {}避免报错 - 确保
data.js中存在对应每个Widget的数据源(比如data3、data4、data5),如果暂时没有,可以先复用现有数据做测试
内容的提问来源于stack exchange,提问作者Justin Greer
相关产品推荐
相关产品推荐

