Reactjs中如何在Playlist组件内访问Vol-Slider组件并动态添加类名
实现方案
不要直接操作原生DOM修改类名,React框架本身是数据驱动视图的,用组件状态控制类名切换才是符合框架设计的写法,也不会出现虚拟DOM重渲染覆盖手动修改的DOM属性的问题。
第一步:修改VolSlider组件
首先移除组件里写死的固定id,你当前16个滑块全用同一个idvol-slider-div违反HTML规范,会导致DOM选择异常。改造组件让它接收外部传入的激活状态,根据状态动态绑定需要的类名:
// 注意组件名要遵循大驼峰命名规范,原代码中小写开头的volSlider不符合React组件要求 export default function VolSlider({ active }) { return ( <div className={`vol-slider-wrap ${active ? '你需要添加的目标类名' : ''}`}> <input className="vol-slider" type="range" min="0" max="100" step="1" /> </div> ); }
第二步:改造Playlist组件
把重复的图标项抽成配置数组循环渲染,用状态数组记录每一项的激活状态,点击时切换对应索引的状态,同时把状态传给图标容器和对应的VolSlider组件,自动控制类名:
import { useState } from 'react'; // 把所有用到的图标按顺序放进配置数组 const SOUND_ICONS = [ BsCloudRain, GiForest, MdOutlineWaterDrop, BiWind, GiCampfire, GiThreeLeaves, BsMoonStars, BiWater, BiTrain, BiCoffeeTogo, FaFan, DiDigitalOcean, GiWaterfall, FaPlane, IoIosPlanet, GiOctopus ]; export default function Playlist() { // 初始化状态数组,默认所有项都是未激活状态 const [activeList, setActiveList] = useState(new Array(SOUND_ICONS.length).fill(false)); const toggleActive = (index) => { setActiveList(prev => { const newState = [...prev]; newState[index] = !newState[index]; return newState; }); }; return ( <div id="playlist-container"> <div id="playlist"> {SOUND_ICONS.map((IconComp, idx) => ( <div key={idx} className={`icons ${activeList[idx] ? 'active' : ''}`} onClick={() => toggleActive(idx)} > <IconComp /> <VolSlider active={activeList[idx]} /> </div> ))} </div> </div> ); }
可选:保留原有逐行写节点的写法
如果你不想抽数组循环,也可以给每个图标单独定义状态,只是代码冗余度很高:
import { useState } from 'react'; export default function Playlist() { const [rainActive, setRainActive] = useState(false); const [forestActive, setForestActive] = useState(false); // 剩余14个图标对应的状态按这个格式依次定义即可 return ( <div id="playlist-container"> <div id="playlist"> <div className={`icons ${rainActive ? 'active' : ''}`} onClick={() => setRainActive(!rainActive)}> <BsCloudRain /> <VolSlider active={rainActive} /> </div> <div className={`icons ${forestActive ? 'active' : ''}`} onClick={() => setForestActive(!forestActive)}> <GiForest /> <VolSlider active={forestActive} /> </div> {/* 剩余节点按相同规则替换即可 */} </div> </div> ); }
注意:不要用
e.currentTarget.querySelector之类的原生DOM方法找子组件节点加类,React重渲染时会把你手动加的类覆盖,后续维护也很容易出问题。
内容的提问来源于stack exchange,提问作者Karan Rajput
相关产品推荐
相关产品推荐

