React-实现切换tab高亮显示和排序
1、切换className
<div className="tab-list">{ tabList.map(item => (<span key={item.type} className={`tab-box ${item.type === type ? 'active' : ''}`} onClick={() => handleClickTab(item.type)}>{ item.name }</span>))}
</div>
2、classNames优化类名控制
上面1的写法如果类名非常多的情况下比较复杂,我们可以引入classNames优化类名控制
// 安装
npm i classnames
// 引入
import classNames from 'classnames';// 使用
<div className="tab-list">{ tabList.map(item => (<span key={item.type} className={classNames('tab-box', {active: item.type === type})} onClick={() => handleClickTab(item.type)}>{ item.name }</span>))}
</div>
3、切换时触发重新排序
以下方法切换tab时不会切换排序,因为这里原地修改原数组,但React的setState需要通过新引用触发重新渲染。由于原数组的引用未改变,React无法感知变化
const [commentList, setCommentList] = useState(list.sort((x, y) => new Date(y.ctime) - new Date(x.ctime)))const [type, setType] = useState('new')
const handleClickTab = (type) => {setType(type)if (type === 'new') {setCommentList(commentList.sort((x, y) => new Date(y.ctime) - new Date(x.ctime)))} else {setCommentList(commentList.sort((x, y) => y.like - x.like))}
}
修改方法一:
setCommentList([...commentList].sort((x, y) => new Date(y.ctime) - new Date(x.ctime)))
修改方法二:函数式更新 => 推荐
setCommentList(prev => prev.sort((x, y) => new Date(y.ctime) - new Date(x.ctime)))
3、完整代码
import { useState } from "react";const list = [{ id: 1,user: {uid: '12244',avatar: 'https://img0.baidu.com/it/u=2191392668,814349101&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=1399',uname: '周杰伦'},content: '哎哟,不错哦',ctime: '2021-06-08 19:35:47',like: 88},{ id: 2,user: {uid: '12245',avatar: 'https://img0.baidu.com/it/u=2191392668,814349101&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=1399',uname: '林俊杰'},content: '好听呀',ctime: '2021-06-15 19:35:47',like: 52},{ id: 3,user: {uid: '12246',avatar: 'https://img0.baidu.com/it/u=2191392668,814349101&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=1399',uname: '周笔畅'},content: '呵呵哈哈哈',ctime: '2021-06-02 19:35:47',like: 192}
]const userInfo = {uid: '12245',avatar: 'https://img0.baidu.com/it/u=2191392668,814349101&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=1399',uname: '林俊杰'
}const tabList = [{ type: 'new', name: '最新' },{ type: 'hot', name: '最热' },
]function App() {const [commentList, setCommentList] = useState(list.sort((x, y) => new Date(y.ctime) - new Date(x.ctime)))const handleDelete = (id) => {setCommentList(commentList.filter(item => item.id !== id))}const [type, setType] = useState('new')const handleClickTab = (type) => {setType(type)if (type === 'new') {// 不会切换排序,因为这里原地修改原数组,但React的setState需要通过新引用触发重新渲染。由于原数组的引用未改变,React无法感知变化// setCommentList(commentList.sort((x, y) => new Date(y.ctime) - new Date(x.ctime)))// 修改方法一// setCommentList([...commentList].sort((x, y) => new Date(y.ctime) - new Date(x.ctime)))// 修改方法二(函数式更新 => 推荐)setCommentList(prev => prev.sort((x, y) => new Date(y.ctime) - new Date(x.ctime)))} else {// setCommentList(commentList.sort((x, y) => y.like - x.like))// setCommentList([...commentList].sort((x, y) => y.like - x.like))setCommentList(prev => prev.sort((x, y) => y.like - x.like))}}return (<div className="App"><div className="tab-list">{ tabList.map(item => (<span key={item.type} className={`tab-box ${item.type === type ? 'active' : ''}`} onClick={() => handleClickTab(item.type)}>{ item.name }</span>))}</div><div className="user-list">{ commentList.map((item, index) => (<div key={index} className="user-box"><img style={{width: 40, height: 40}} src={item.user.avatar} /><span>{ item.user.uname }</span><div>{ item.content }</div><div>{ item.ctime }</div><span>点赞数:{ item.like }</span>{ userInfo.uid === item.user.uid && <button onClick={() => handleDelete(item.id)}>删除</button> }</div>))}</div></div>);
}export default App;