快来退出咱们吧!
"小和山的菜鸟们",为前端开发者提供技术相干资讯以及系列根底文章。为更好的用户体验,请您移至咱们官网小和山的菜鸟们 ( 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 办法以及一些相干内容。敬请期待!