该Demo涉及的技术点
- useState函数(数据驱动视图)
- 子组件的封装
- 条件判断
- 回调函数的封装
1、评论数据
{
"list": [
{
"rpid": 3,
"user": {
"uid": "13258165",
"avatar": "http://toutiao.itheima.net/resources/images/98.jpg",
"uname": "周杰伦"
},
"content": "哎哟,不错哦",
"ctime": "10-18 08: 15",
"like": 126
},
{
"rpid": 2,
"user": {
"uid": "36080105",
"avatar": "http://toutiao.itheima.net/resources/images/98.jpg",
"uname": "许嵩"
},
"content": "我寻你千百度 日出到迟暮",
"ctime": "11-13 11: 29",
"like": 88
},
{
"rpid": 1,
"user": {
"uid": "30009257",
"avatar": "http://toutiao.itheima.net/resources/images/98.jpg",
"uname": "前端"
},
"content": "前端真好玩",
"ctime": "10-19 09: 00",
"like": 66
}
]
}
2、具体实现
- 获取json中的list数据 (读取本地文件 / 读取接口)
const JsonReader = () => {
const [ commentList, setCommentList ] = useState([]);
useEffect(() => {
fetch('_db.json')
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(data => {
setCommentList(_.orderBy(data.list, 'like', 'desc'));
})
.catch(error => {
console.error('There has been a problem with your fetch operation:', error);
});
}, []);
return {
commentList,
setCommentList
}
}
function useGetList () {
const [commentList, setCommentList] = useState([])
useEffect(() => {
async function getList () {
const res = await axios.get(' http://localhost:3004/list')
setCommentList(res.data)
}
getList()
}, [])
return {
commentList,
setCommentList
}
}
const user = {
uid: '30009257',
avatar,
uname: '黑马前端',
}
const tabs = [
{ type: 'hot', text: '最热' },
{ type: 'time', text: '最新' },
]
function Item ({ item, onDel }) {
return (
<div className="reply-item">
{}
<div className="root-reply-avatar">
<div className="bili-avatar">
<img
className="bili-avatar-img"
alt=""
src={item.user.avatar}
/>
</div>
</div>
<div className="content-wrap">
{}
<div className="user-info">
<div className="user-name">{item.user.uname}</div>
</div>
{}
<div className="root-reply">
<span className="reply-content">{item.content}</span>
<div className="reply-info">
{}
<span className="reply-time">{item.ctime}</span>
{}
<span className="reply-time">点赞数:{item.like}</span>
{}
{user.uid === item.user.uid &&
<span className="delete-btn" onClick={() => onDel(item.rpid)}>
删除
</span>}
</div>
</div>
</div>
</div>
)
}
const App = () => {
const { commentList, setCommentList } = JsonReader()
const handleDel = (id) => {
console.log(id)
setCommentList(commentList.filter(item => item.rpid !== id))
}
const [type, setType] = useState('hot')
const handleTabChange = (type) => {
console.log(type)
setType(type)
if (type === 'hot') {
setCommentList(_.orderBy(commentList, 'like', 'desc'))
} else {
setCommentList(_.orderBy(commentList, 'ctime', 'desc'))
}
}
const [content, setContent] = useState('')
const inputRef = useRef(null)
const handlPublish = () => {
setCommentList([
...commentList,
{
rpid: uuidV4(),
user: {
uid: '30009257',
avatar,
uname: '黑马前端',
},
content: content,
ctime: dayjs(new Date()).format('MM-DD hh:mm'),
like: 66,
}
])
setContent('')
inputRef.current.focus()
}
return (
<div className="app">
{}
<div className="reply-navigation">
<ul className="nav-bar">
<li className="nav-title">
<span className="nav-title-text">评论</span>
{}
<span className="total-reply">{10}</span>
</li>
<li className="nav-sort">
{}
{tabs.map(item =>
<span
key={item.type}
onClick={() => handleTabChange(item.type)}
className={classNames('nav-item', { active: type === item.type })}>
{item.text}
</span>)}
</li>
</ul>
</div>
<div className="reply-wrap">
{}
<div className="box-normal">
{}
<div className="reply-box-avatar">
<div className="bili-avatar">
<img className="bili-avatar-img" src={avatar} alt="用户头像" />
</div>
</div>
<div className="reply-box-wrap">
{}
<textarea
className="reply-box-textarea"
placeholder="发一条友善的评论"
ref={inputRef}
value={content}
onChange={(e) => setContent(e.target.value)}
/>
{}
<div className="reply-box-send">
<div className="send-text" onClick={handlPublish}>发布</div>
</div>
</div>
</div>
{}
<div className="reply-list">
{}
{commentList.map(item => <Item key={item.id} item={item} onDel={handleDel} />)}
</div>
</div>
</div>
)
}
最终效果:
