實戰分析:評論功能(三)

接下來的代碼比較瓜熟蒂落了。修改 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 找到, 在線演示 體驗。

總結

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

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

固然,在真實的項目當中,這個案例不少地方是能夠優化的。包括組件可複用性方面(有沒有發現其實 CommentInput 中有重複的代碼?)、應用的狀態管理方面。但在這裏爲了給你們總結和演示,實現到這個程度也就足夠了。

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

相關文章
相關標籤/搜索