React.js 小書 Lesson16 - 實戰分析:評論功能(三)


接下來的代碼比較順理成章了。修改 CommentList 可以讓它可以顯示評論列表:

// CommentList.js import React, { Component } from 'react' class CommentList extends Component { render() { const comments = [ {username: 'Jerry', content: 'Hello'}, {username: 'Tomy', content: 'World'}, {username: 'Lucy', content: 'Good'} ] return ( <div>{comments.map((comment, i) => { return ( <div key={i}> {comment.username}:{comment.content} </div> ) })}</div> ) } } export default CommentList 

這里的代碼沒有什么新鮮的內容,只不過是建立了一個 comments 的數組來存放一些測試數據的內容,方便我們后續測試。然后把 comments 的數據渲染到頁面上,這跟我們之前講解的章節的內容一樣——使用 map 構建一個存放 JSX 的數組。就可以在瀏覽器看到效果:

React.js 小書實戰之評論功能圖片

修改 Comment.js 讓它來負責具體每條評論內容的渲染:

import React, { Component } from 'react' class Comment extends Component { render () { return ( <div className='comment'> <div className='comment-user'> <span>{this.props.comment.username} </span>: </div> <p>{this.props.comment.content}</p> </div> ) } } export default Comment 

這個組件可能是我們案例里面最簡單的組件了,它只負責每條評論的具體顯示。你只需要給它的 props 中傳入一個 comment 對象,它就會把該對象中的 username 和 content 渲染到頁面上。

馬上把 Comment 應用到 CommentList 當中,修改 CommentList.js 代碼:

import React, { Component } from 'react' import Comment from './Comment' class CommentList extends Component { render() { const comments = [ {username: 'Jerry', content: 'Hello'}, {username: 'Tomy', content: 'World'}, {username: 'Lucy', content: 'Good'} ] return ( <div> {comments.map((comment, i) => <Comment comment={comment} key={i} />)} </div> ) } } export default CommentList 

可以看到測試數據顯示到了頁面上:

React.js 小書實戰之評論功能圖片

之前我們說過 CommentList 的數據應該是由父組件 CommentApp 傳進來的,現在我們刪除測試數據,改成從 props 獲取評論數據:

import React, { Component } from 'react' import Comment from './Comment' class CommentList extends Component { render() { return ( <div> {this.props.comments.map((comment, i) => <Comment comment={comment} key={i} /> )} </div> ) } } export default CommentList 

這時候可以看到瀏覽器報錯了:

React.js 小書實戰之評論功能圖片

這是因為CommentApp 使用 CommentList 的時候並沒有傳入 comments。我們給 CommentList 加上 defaultProps 防止 comments 不傳入的情況:

class CommentList extends Component { static defaultProps = { comments: [] } ... 

這時候代碼就不報錯了。但是 CommentInput 給 CommentApp 傳遞的評論數據並沒有傳遞給 CommentList,所以現在發表評論時沒有反應的。

我們在 CommentApp 的 state 中初始化一個數組,來保存所有的評論數據,並且通過 props 把它傳遞給 CommentList。修改 CommentApp.js

import React, { Component } from 'react' import CommentInput from './CommentInput' import CommentList from './CommentList' class CommentApp extends Component { constructor () { super() this.state = { comments: [] } } handleSubmitComment (comment) { console.log(comment) } render() { return ( <div className='wrapper'> <CommentInput onSubmit={this.handleSubmitComment.bind(this)} /> <CommentList comments={this.state.comments}/> </div> ) } } export default CommentApp 

接下來,修改 handleSubmitComment :每當用戶發布評論的時候,就把評論數據插入 this.state.comments 中,然后通過 setState 把數據更新到頁面上:

...
  handleSubmitComment (comment) {
    this.state.comments.push(comment) this.setState({ comments: this.state.comments }) } ... 

小提示:這里的代碼直接往 state.comments 數組里面插入數據其實違反了 React.js 的 state 不可直接修改的原則 。但其實這個原則是為了 shouldComponentUpdate 的優化和變化的跟蹤,而這種目的在使用 React-redux 的時候其實會自然而然達到,我們很少直接手動地優化,這時候這個原則就會顯得有點雞肋。所以這里為了降低大家的理解成本就不強制使用這個原則,有興趣的朋友可以參考: Tutorial: Intro To React - React

現在代碼應該是可以按照需求正常運作了,輸入用戶名和評論內容,然后點擊發布:

React.js 小書實戰之評論功能圖片

為了讓代碼的健壯性更強,給 handleSubmitComment 加入簡單的數據檢查:

...
  handleSubmitComment (comment) {
    if (!comment) return if (!comment.username) return alert('請輸入用戶名') if (!comment.content) return alert('請輸入評論內容') this.state.comments.push(comment) this.setState({ comments: this.state.comments }) } ... 

到這里,我們的第一個實戰案例——評論功能已經完成了!完整的案例代碼可以在這里 comment-app 找到, 在線演示 體驗。

總結

在這個案例里面,我們除了復習了之前所學過的內容以外還學習了新的知識點。包括:

  1. 實現功能之前先理解、分析需求,划分組件。並且掌握划分組件的基本原則——可復用性、可維護性。
  2. 受控組件的概念,React.js 中的 <input /> 、<textarea /><select /> 等元素的 value 值如果是受到 React.js 的控制,那么就是受控組件。
  3. 組件之間使用 props 通過父元素傳遞數據的技巧。

當然,在真實的項目當中,這個案例很多地方是可以優化的。包括組件可復用性方面(有沒有發現其實 CommentInput 中有重復的代碼?)、應用的狀態管理方面。但在這里為了給大家總結和演示,實現到這個程度也就足夠了。

到此為止,React.js 小書的第一階段已經結束,你可以利用這些知識點來構建簡單的功能模塊了。但是在實際項目如果要構建比較系統和完善的功能,還需要更多的 React.js 的知識還有關於前端開發的一些認知來協助我們。接下來我們會開啟新的一個階段來學習更多關於 React.js 的知識,以及如何更加靈活和熟練地使用它們。讓我們進入第二階段吧!


因為第三方評論工具有問題,對本章節有任何疑問的朋友可以移步到 React.js 小書的論壇 發帖,我會回答大家的疑問。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM