接下來的代碼比較瓜熟蒂落了。修改 CommentList
可讓它能夠顯示評論列表:html
// 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 的數組。就能夠在瀏覽器看到效果:前端
修改 Comment.js
讓它來負責具體每條評論內容的渲染:react
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
渲染到頁面上。git
立刻把 Comment
應用到 CommentList
當中,修改 CommentList.js
代碼:github
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
能夠看到測試數據顯示到了頁面上:redux
以前咱們說過 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
這時候能夠看到瀏覽器報錯了:瀏覽器
這是由於CommentApp
使用 CommentList
的時候並無傳入 comments
。咱們給 CommentList
加上 defaultProps
防止 comments
不傳入的狀況:app
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。
如今代碼應該是能夠按照需求正常運做了,輸入用戶名和評論內容,而後點擊發布:
爲了讓代碼的健壯性更強,給 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 找到, 在線演示 體驗。
在這個案例裏面,咱們除了複習了以前所學過的內容之外還學習了新的知識點。包括:
<input />
、<textarea />
、<select />
等元素的 value
值若是是受到 React.js 的控制,那麼就是受控組件。props
經過父元素傳遞數據的技巧。固然,在真實的項目當中,這個案例不少地方是能夠優化的。包括組件可複用性方面(有沒有發現其實 CommentInput
中有重複的代碼?)、應用的狀態管理方面。但在這裏爲了給你們總結和演示,實現到這個程度也就足夠了。
到此爲止,React.js 小書的第一階段已經結束,你能夠利用這些知識點來構建簡單的功能模塊了。可是在實際項目若是要構建比較系統和完善的功能,還須要更多的 React.js 的知識還有關於前端開發的一些認知來協助咱們。接下來咱們會開啓新的一個階段來學習更多關於 React.js 的知識,以及如何更加靈活和熟練地使用它們。讓咱們進入第二階段吧!