join us!
Mountain" , to provide front-end developers with technical information and a series of basic articles. For a better user experience, please move to our official website novices (160e55f0b532bd https://xhs-rookies.com/ ) to learn and get the latest articles in time.
"Code tailor" , if you are interested in our article or want to make some suggestions, follow Mountain" public account, contact us, you can also watch it on WeChat Our article. Every suggestion or approval is a great encouragement to us!
Practical case (3): Revised version of the message function
We learned some new content this time, and we need to revise the previous version.
Added like function
What if we need to like a comment?
If you pass in a certain attribute to control whether to show likes as you did last time, this is okay.
We abstracted the InputCompoent
input box component and the EvaluateCompoent
list display component last time. This time we need to add a comment
component to complete the like function.
Unnecessary component removal
Last time we InputCompoent
input box component and the EvaluateCompoent
list display component and placed them in the component
folder. We first placed these two components directly in App.js
. (For the sake of intuition, let's put these two already abstracted directly in App.js
)
We only need to abstract a comment
component, add our like function to the last EvaluateCompoent
list display component, and we can like each comment in the list.
Therefore, we App.js
as follows:
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
Combining comment components
Like function
First of all, we need to consider what functions this component requires.
In addition to the last abstraction:
In addition to the avatar, time, name, and content, we also need a like button. This button will turn red with one click, and the number will increase by one, click again to change the color to gray again, and the number will decrease by one.
<span className={'likeBox ' + (liked ? 'like' : 'unlike')} onClick={() => changeLike()}>
<span className="icon"> </span>
<span>{!!likeNum && likeNum}</span>
</span>
One span
used to store the like icon, and one is used to display the like number.
Data detection
This time we have more data. After more and more data is passed to the component from the outside, how do we judge, or guarantee that the incoming content is correct? (Is it empty?)
We use propType
for content detection. If there is an error, we can quickly help us locate the error and make corrections.
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,
}
Final combination
Then we add the previous EvaluateCompoent
list display component with the like function, after adding the data detection function, our comment
component is complete.
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
Source address
Direct preview
We recommend using codesanbox
to quickly access current actual combat cases online.
Preview of the next section
In the next section, we will talk about the use of State in React related information, in-depth understanding of the setState method and some related content. Stay tuned!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。