如何在React中根据点击按钮切换对应Div的active类?
解决React类组件中多元素的active类切换问题
我来帮你搞定这个类切换的问题!你现在的核心问题是只用了一个布尔值的state,没法区分两个不同的Overlay组件。咱们调整一下state的结构,就能实现每个按钮精准控制对应Overlay的激活状态了。
具体修改步骤:
1. 更新Product组件的state结构
把原来单个布尔值的active改成存储当前激活的Overlay标识,这样就能区分不同的元素了:
constructor(props) { super(props); this.toggleClass= this.toggleClass.bind(this); this.state = { activeOverlay: null, // 用字符串标识激活项,比如'overlay1'/'overlay2',null表示都不激活 }; }
2. 改写toggleClass方法,支持指定目标Overlay
让方法接收一个参数,用来判断要切换哪个Overlay的状态:
toggleClass(overlayId) { // 逻辑:如果点击的是当前激活的项,就取消激活;否则设置该项为激活状态 this.setState(prevState => ({ activeOverlay: prevState.activeOverlay === overlayId ? null : overlayId })); };
3. 给每个按钮绑定对应的点击事件
给每个Link添加点击事件,传入对应Overlay的标识,同时阻止默认的跳转行为(如果你的Link不需要跳转的话):
<Link onClick={(e) => { e.preventDefault(); // 阻止Link默认的页面跳转 this.toggleClass('overlay1'); }} className="btn-reverse overlay" >TOC</Link> <Link onClick={(e) => { e.preventDefault(); this.toggleClass('overlay2'); }} className="btn-reverse overlay" >Puresure</Link>
4. 让Overlay组件根据props动态添加active类
修改Overlay组件,接收isActive属性,然后动态生成className:
class Overlay extends React.Component { render() { // 拼接类名:基础overlay类 + 可选的active类 const overlayClassName = `overlay ${this.props.isActive ? 'active' : ''}`; return ( <div className={overlayClassName}> <h2>{this.props.text}</h2> </div> ) } }
然后在Product组件渲染Overlay的时候,传入对应的isActive判断:
<Overlay text={'Overlay 1'} isActive={this.state.activeOverlay === 'overlay1'} /> <Overlay text={'Overlay 2'} isActive={this.state.activeOverlay === 'overlay2'} />
完整修改后的代码
import React, { useContext } from "react"; import { Link } from "react-router-dom"; import '../App.scss'; import ProductData from "./data/ProductData"; import { ChoicesContext } from "../context/ChoicesProvider"; class Product extends React.Component { constructor(props) { super(props); this.toggleClass= this.toggleClass.bind(this); this.state = { activeOverlay: null, }; } toggleClass(overlayId) { this.setState(prevState => ({ activeOverlay: prevState.activeOverlay === overlayId ? null : overlayId })); }; static contextType = ChoicesContext; render() { const { choices } = this.context; const CurrentProduct = ProductData.filter(x => x.name === choices.productSelected); return ( <> <div className="product wrapper d-md-flex"> <main> <Link onClick={(e) => { e.preventDefault(); this.toggleClass('overlay1'); }} className="btn-reverse overlay" >TOC</Link> <Link onClick={(e) => { e.preventDefault(); this.toggleClass('overlay2'); }} className="btn-reverse overlay" >Puresure</Link> <Overlay text={'Overlay 1'} isActive={this.state.activeOverlay === 'overlay1'} /> <Overlay text={'Overlay 2'} isActive={this.state.activeOverlay === 'overlay2'} /> </main> </div> </> ) } } class Overlay extends React.Component { render() { const overlayClassName = `overlay ${this.props.isActive ? 'active' : ''}`; return ( <div className={overlayClassName}> <h2>{this.props.text}</h2> </div> ) } } export default Product;
这样修改后,点击每个按钮就只会给对应的Overlay添加/移除active类了。如果需要支持同时激活多个Overlay,只需要把state改成对象存储每个Overlay的激活状态即可,比如activeOverlays: { overlay1: false, overlay2: false },然后toggle的时候单独切换对应项的布尔值。
内容的提问来源于stack exchange,提问作者BEDev
相关产品推荐
相关产品推荐

