React记事本项目:点击单条笔记添加类样式异常求助
问题分析与解决
问题1:所有笔记同时被选中
你现在用布尔值selected控制选中状态,所有笔记都会基于同一个变量判断是否添加selected类,只要selected变为true,所有笔记都会被选中。
解决方法:把选中状态改成存储选中笔记的索引(或唯一ID),精准定位单个笔记:
- 将
const [selected, setSelect] = React.useState(false)替换为const [selectedIndex, setSelectedIndex] = React.useState(null)(null表示无选中笔记) - 修改
selectFunction,直接设置选中索引,点击已选中笔记时取消选中:
function selectFunction(index) { setSelectedIndex(prev => prev === index ? null : index); }
- 渲染时判断当前笔记索引是否等于
selectedIndex来添加类:
className={`note-box ${selectedIndex === index ? 'selected' : ''}`}
- 简化
onClick调用,直接传index即可:onClick={()=> selectFunction(index)}
问题2:内容显示错乱
这是因为你用index作为key,删除笔记后剩余笔记的index会重新排序,React的diff算法会复用旧DOM节点,导致内容与节点不匹配。
解决方法:给每个笔记添加唯一标识(比如创建时生成id字段),用这个唯一值作为key:
- 若
notesContainer里的note对象有id属性(比如用Date.now()或uuid生成),把key={index}改成key={note.id} - 暂时没有唯一id的话,可先用
note.notes + index临时替代,但建议尽快给每个笔记添加唯一id
额外优化:阻止删除图标事件冒泡
点击删除图标时会触发父元素的选中事件,需在删除点击事件里阻止冒泡:
<FontAwesomeIcon onClick={(e) => { e.stopPropagation(); del(index); }} icon={faCircleXmark} className='icon' />
修改后的完整代码
export default function Sidebar() { const { notesContainer, setNotesContainer } = React.useContext(notesContext) function del(index) { const notesCopy = [...notesContainer] notesCopy.splice(index, 1) setNotesContainer(notesCopy) } const [selectedIndex, setSelectedIndex] = React.useState(null) function selectFunction(index) { setSelectedIndex(prev => prev === index ? null : index) } return ( <div> {notesContainer.map((note, index) => { return ( <div onClick={()=> selectFunction(index)} id={index} className={`note-box ${selectedIndex === index ? 'selected' : ''}`} key={note.id || index} > {note.notes} <FontAwesomeIcon onClick={(e) => { e.stopPropagation(); del(index); }} icon={faCircleXmark} className='icon' /> </div> ) }) } </div> ) }
内容的提问来源于stack exchange,提问作者aliboxer
相关产品推荐
相关产品推荐

