React应用无法切换标签页问题求助,如何实现点击切换标签内容
现有实现问题分析
原生DOM操作版本问题
onClick绑定逻辑错误:你直接写了onClick={openPage('upcoming_estimates',this)},相当于组件渲染时就会立即执行openPage函数,而不是点击时触发,正确写法应该是包裹成箭头函数onClick={() => openPage('upcoming_estimates',this)}- 选择器匹配失败:你的逻辑里通过
getElementsByClassName("tabcontent")找内容区块,但两个内容div根本没有加tabcontent类名,所以无法隐藏其他区块 - React不推荐直接操作DOM,容易和虚拟DOM渲染逻辑冲突,出现不可预期的展示问题
react-router路由版本问题
- 普通
button没有href属性,无法触发路由跳转,需要用react-router提供的Link组件或者useNavigate钩子实现跳转 UpcomingEstimates和EstimatesSent两个组件是定义在Estimates组件内部的,App.js作用域下无法访问这两个组件,所以路由配置里的渲染逻辑会直接报错- 现有路由配置跳转后会丢失
Estimates页面的公共布局(侧边栏、头部、搜索栏等),不符合标签页在当前页切换内容的需求
推荐解决方案:用React本地状态实现标签页(改动最小)
不需要引入路由,直接用useState控制当前激活的标签即可,符合React声明式编程逻辑,代码如下:
import React, { useState } from 'react'; import './Dashboard.css'; import 'font-awesome/css/font-awesome.min.css'; import logo2 from './logo2.svg'; import clock from './clock.svg'; const Estimates = () => { // 定义激活标签状态,默认展示即将到来的估算 const [activeTab, setActiveTab] = useState('upcoming_estimates') return ( <div className="dashboardHome"> <div className="SideBar"> <div className="logo"> <img src={logo2} className="dashlogo" alt="logo" /> </div> </div> <div className="headerArea"> <div> <p><img src={clock} className="clock" alt="clock" /><font className="headerAreaDir"><h4>Estimating</h4></font></p> </div> </div> <div className="dataArea"> <div> <input type="text" placeholder="  Search customers by name" className="searchBox" /> <p className="SearchFilterClass">Filter by: <select className="MySelector"> <option>7 Days</option> <option>14 Days</option> <option>21 Days</option> </select> </p> </div> <div className="estimates_area"> <button className={activeTab === 'upcoming_estimates' ? 'active_tab' : ''} onClick={() => setActiveTab('upcoming_estimates')} > Upcoming Estimates </button> <button className={activeTab === 'estimates_sent' ? 'active_tab' : ''} onClick={() => setActiveTab('estimates_sent')} > Estimates Sent </button> <div> {/* 根据激活状态判断展示哪个内容 */} {activeTab === 'upcoming_estimates' && ( <div id="upcoming_estimates"> <h2>upcoming Estimates</h2> <p>This area is for upcoming estimates</p> </div> )} {activeTab === 'estimates_sent' && ( <div id="estimates_sent"> <h2>Sent Estimates</h2> <p>This area is for Sent Estimates</p> </div> )} </div> </div> </div> </div> ) } export default Estimates;
你可以自行在css里添加.active_tab类的样式,用来高亮当前选中的标签。
如果你一定要用路由实现标签页
需要做以下修改:
- 把
UpcomingEstimates和EstimatesSent两个组件抽成单独的js文件,分别导出,在App.js中引入 - 使用嵌套路由,把两个标签内容作为Estimates页面的子路由,保留公共布局
- 把标签按钮替换为react-router的
Link组件,指向对应子路由路径
内容的提问来源于stack exchange,提问作者Revan
相关产品推荐
相关产品推荐

