快来退出咱们吧!
“ 小和山的菜鸟们 ”,为前端开发者提供技术相干资讯以及系列根底文章。为更好的用户体验,请您移至咱们官网小和山的菜鸟们 (https://xhs-rookies.com/) 进行学习,及时获取最新文章。
“Code tailor”,如果您对咱们文章感兴趣、或是想提一些倡议,微信关注 “小和山的菜鸟们” 公众号,与咱们取的分割,您也能够在微信上观看咱们的文章。每一个倡议或是同意都是对咱们极大的激励!
实战案例(三):留言性能改版
咱们这次学了一些新内容,咱们须要将之前的改版。
新增点赞性能
如果咱们须要对某个评论进行点赞怎么办呢?
如果依照上次那样子通过某个属性传入管制是否显示点赞,这是能够的。
咱们上次形象了 InputCompoent
输入框组件和 EvaluateCompoent
列表展现组件这两个组件,这次咱们须要新增一个 comment
组件来实现点赞性能。
不须要的组件去除
上次咱们将 InputCompoent
输入框组件和 EvaluateCompoent
列表展现组件形象进去搁置于 component
文件夹中,咱们先将这两个组件间接搁置于 App.js
中。(为了直观,咱们先这两个曾经形象好的给间接搁置于 App.js
中)
咱们只须要形象一个 comment
组件,给上次的 EvaluateCompoent
列表展现组件加上咱们的点赞性能,每个列表中的评论咱们都能够进行点赞。
因而咱们将首页 App.js
批改为如下:
import React, {PureComponent} from 'react'
import Comment from './comment'
import './App.css'
class App extends PureComponent {constructor() {super()
this.state = {
title: 'Hello React',
desc: '你晓得有这么一个团队吗?他们怀揣幻想,艰苦奋斗,作为一群大学生菜鸟,放弃了平时娱乐的工夫,抉择一起学习,一起成长,将平时学习的笔记,心得总结为文章,目标很简略,心愿能够帮忙向他们一样的菜鸟们?你想理解更多吗?快搜寻微信公众号:小和山的菜鸟们,退出他们吧!',
comments: [
{
headPortrait: 'https://xhs-rookies.com/img/rookie-icon.png',
time: new Date(2021, 4, 14, 21, 2, 30),
nickName: '小菜鸟',
detail: '这是一个行将推出系列文章的团队,咱们一起期待他们的作品吧!',
liked: true,
likeNum: 23,
},
],
text: '',
}
}
render() {const { title, desc, comments, text} = this.state
return (
<div className="App">
<h2>{title}</h2>
<div className="desc">{desc}</div>
<div style={{width: '100%'}}>
<p className="commentsTitle"> 评论 </p>
{comments.map((item, index) => {
return (
<Comment
key={item.time.getTime()}
changeLike={() => {this.changeLike(index)
}}
{...item}
/>
)
})}
</div>
<div className="newComment">
<div style={{display: 'flex'}}>
<img src="https://xhs-rookies.com/img/rookie-icon.png" className=""alt="" />
<textarea value={text} onChange={(e) => this.changeText(e)} placeholder="请输出评论" />
</div>
<div
className="submit"
onClick={() => {this.addComment()
}}
>
发表
</div>
</div>
</div>
)
}
changeText(e) {this.setState({ text: e.target.value})
}
changeLike(index) {let newArray = [...this.state.comments]
let newItem = {...newArray[index] }
if (newItem.liked) {
newItem.liked = false
newItem.likeNum -= 1
} else {
newItem.liked = true
newItem.likeNum += 1
}
newArray[index] = newItem
this.setState({comments: newArray,})
}
addComment() {if (!this.state.text) {alert('请输出留言内容')
return
}
let detail = this.state.text
this.setState({text: ''})
let newComment = {
headPortrait: 'https://xhs-rookies.com/img/rookie-icon.png',
time: new Date(),
nickName: '小菜鸟',
detail,
liked: false,
likeNum: 0,
}
this.setState({comments: [newComment, ...this.state.comments],
})
}
}
App.propTypes = {}
export default App
组合 comment 组件
点赞性能
首先咱们须要思考这个组件须要什么性能。
除了上次形象进去的:
须要有头像、工夫、名字、内容这几个外,咱们还须要一个点赞按钮,这个按钮点击一下变成红色,并且数字加一,再次点击色彩从新改为灰色,并且数字减一。
<span className={'likeBox' + (liked ? 'like' : 'unlike')} onClick={() => changeLike()}>
<span className="icon"> </span>
<span>{!!likeNum && likeNum}</span>
</span>
一个 span
用于寄存点赞图标,一个用于显示点赞的数字。
数据检测
这次咱们数据变得更加多了,里面传给该组件的数据越来越多之后,咱们如何判断,或是说保障给进来内容是正确的呢?(是否为空?)
咱们采纳 propType
进行内容检测,如果呈现谬误,能够疾速帮咱们定位谬误并进行批改。
Comment.propTypes = {
nickName: PropTypes.string.isRequired,
time: PropTypes.object.isRequired,
headPortrait: PropTypes.string.isRequired,
detail: PropTypes.string.isRequired,
liked: PropTypes.bool.isRequired,
likeNum: PropTypes.number.isRequired,
changeLike: PropTypes.func.isRequired,
}
最终组合
那咱们将之前的 EvaluateCompoent
列表展现组件加上点赞性能,在将数据检测性能增加进去,咱们的 comment
组件就实现了。
import React, {PureComponent} from 'react'
import PropTypes from 'prop-types'
import './comment.css'
class Comment extends PureComponent {render() {const { nickName, time, headPortrait, detail, liked, likeNum, changeLike} = this.props
return (
<div className="comment">
<div className="info">
<img src={headPortrait} alt="头像" />
<div>
<p className="nickname">{nickName}</p>
<p className="time">{this.getTime(time)}</p>
</div>
</div>
<div className="detail" style={{marginBottom: '10px'}}>
{detail}
</div>
<div className="toolBox">
<span className={'likeBox' + (liked ? 'like' : 'unlike')} onClick={() => changeLike()}>
<span className="icon"> </span>
<span>{!!likeNum && likeNum}</span>
</span>
<span className="share icon"> </span>
</div>
</div>
)
}
getTime(time) {const year = time.getFullYear()
const month = time.getMonth() + 1
const day = time.getDate()
const hour = String(time.getHours()).padStart(2, '0')
const minute = String(time.getMinutes()).padStart(2, '0')
const second = String(time.getSeconds()).padStart(2, '0')
return `${year}.${month}.${day} ${hour}:${minute}:${second}`
}
}
Comment.propTypes = {
nickName: PropTypes.string.isRequired,
time: PropTypes.object.isRequired,
headPortrait: PropTypes.string.isRequired,
detail: PropTypes.string.isRequired,
liked: PropTypes.bool.isRequired,
likeNum: PropTypes.number.isRequired,
changeLike: PropTypes.func.isRequired,
}
export default Comment
源码地址
我的项目 github 地址
间接预览
咱们倡议采纳 codesanbox
的模式能够在线快速访问以后实战案例。
CodeSandBox
下节预报
下节中咱们将讲述应用 React 中 State 的相干信息,深刻了解 setState 办法以及一些相干内容。敬请期待!