如何用React SCSS为选中项的上下及后续列表元素设置差异化样式
问题解决:为选中项上方元素设置差异化样式
我已经实现选中项下方紧邻元素及后续元素的差异化样式,但无法给选中项上方的元素设置不同样式。
期望效果
选中项样式突出,其上方所有元素使用一套统一样式,下方所有元素使用另一套统一样式。
当前问题
仅能修改选中项下方元素的样式,上方元素与选中项样式一致,达不到预期。
现有代码
React 组件代码
import React, { useState } from 'react' import './App.scss' function App() { const [list] = useState([{ time:'10:00', selected:false, },{ time:'10:30', selected:false, },{ time:'11:00', selected:false, },{ time:'11:30', selected:true, },{ time:'12:00', selected:false, },{ time:'12:30', selected:false, },{ time:'01:00', selected:false, }]); return ( <div className='container'> <ul className='list'> {list.map((item) => ( <li key={item.id} className={`item ${item.selected === true ? "selected" : ""}`} > {item.time} </li> ))} </ul> </div> ); } export default App
SCSS 代码
.list{ display: flex; list-style: none; margin: 0; flex-direction: column; } .item{ display: flex; margin: 5px; font-weight: 500; font-size: 19px; line-height: 28px; letter-spacing: 0.35px; background-color: black; color: white; &.selected{ font-weight: 500; font-size: 22px; line-height: 28px; letter-spacing: 0.35px; background-color: black; color: white; &.selected + .item:nth-child(n + 1) { font-weight: 400; font-weight: 500; font-size: 19px; line-height: 28px; letter-spacing: 0.35px; background-color: yellow; } &.selected ~ .item { font-weight: 500; font-size: 15px; line-height: 28px; letter-spacing: 0.35px; background-color: red; } } }
解决方案
由于CSS原生不支持向前选择兄弟元素(即无法通过选中项反向选择它之前的元素),我们可以通过React预先计算每个元素与选中项的位置关系,给对应元素添加专属类名,再通过SCSS设置样式。
修改后的React组件代码
import React, { useState } from 'react' import './App.scss' function App() { const [list] = useState([ { time: '10:00', selected: false }, { time: '10:30', selected: false }, { time: '11:00', selected: false }, { time: '11:30', selected: true }, { time: '12:00', selected: false }, { time: '12:30', selected: false }, { time: '01:00', selected: false } ]); // 找到选中项的索引位置 const selectedIndex = list.findIndex(item => item.selected); return ( <div className='container'> <ul className='list'> {list.map((item, index) => ( <li key={item.time} // 修正key值(原代码无id字段,用time作为唯一标识) className={`item ${item.selected ? 'selected' : ''} ${index < selectedIndex ? 'above-selected' : ''} ${index > selectedIndex ? 'below-selected' : ''} `} > {item.time} </li> ))} </ul> </div> ); } export default App
修改后的SCSS代码
.list{ display: flex; list-style: none; margin: 0; flex-direction: column; } .item{ margin: 5px; font-weight: 500; font-size: 19px; line-height: 28px; letter-spacing: 0.35px; background-color: black; color: white; // 选中项样式 &.selected{ font-size: 22px; // 可根据需求添加其他突出样式 } // 选中项上方元素样式 &.above-selected{ background-color: #333; // 示例样式,可自行修改 font-size: 17px; } // 选中项下方元素样式 &.below-selected{ background-color: red; // 示例样式,可自行修改 font-size: 15px; } }
说明
通过React计算每个元素的索引与选中项索引的关系,给上方元素添加above-selected类,下方元素添加below-selected类,就能轻松实现三类元素的样式区分,避开CSS选择器的局限性,实现逻辑直观且易维护。
内容的提问来源于stack exchange,提问作者Vishnu Vedagna
相关产品推荐
相关产品推荐

