"小和山的菜鳥們",爲前端開發者提供技術相關資訊以及系列基礎文章。爲更好的用戶體驗,請您移至咱們官網小和山的菜鳥們 ( xhs-rookies.com/ ) 進行學習,及時獲取最新文章。css
"Code tailor" ,若是您對咱們文章感興趣、或是想提一些建議,微信關注 「小和山的菜鳥們」 公衆號,與咱們取的聯繫,您也能夠在微信上觀看咱們的文章。每個建議或是贊同都是對咱們極大的鼓勵!前端
咱們此次學了一些新內容,咱們須要將以前的改版。react
若是咱們須要對某個評論進行點贊怎麼辦呢?git
若是按照上次那樣子經過某個屬性傳入控制是否顯示點贊,這是能夠的。github
咱們上次抽象了 InputCompoent
輸入框組件和 EvaluateCompoent
列表展現組件這兩個組件,此次咱們須要新增一個 comment
組件來完成點贊功能。web
不須要的組件去除微信
上次咱們將 InputCompoent
輸入框組件和 EvaluateCompoent
列表展現組件抽象出來放置於 component
文件夾中,咱們先將這兩個組件直接放置於App.js
中。(爲了直觀,咱們先這兩個已經抽象好的給直接放置於 App.js
中)markdown
咱們只須要抽象一個comment
組件,給上次的EvaluateCompoent
列表展現組件加上咱們的點贊功能,每一個列表中的評論咱們均可以進行點贊。oop
所以咱們將首頁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
複製代碼
首先咱們須要考慮這個組件須要什麼功能。
除了上次抽象出來的:
須要有頭像、時間、名字、內容這幾個外,咱們還須要一個點贊按鈕,這個按鈕點擊一下變成紅色,而且數字加一,再次點擊顏色從新改成灰色,而且數字減一。
<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
複製代碼
咱們建議採用 codesanbox
的形式能夠在線快速訪問當前實戰案例。
下節中咱們將講述使用React中State的相關信息,深刻理解 setState 方法以及一些相關內容。敬請期待!