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

持久化評論

一樣地,能夠經過相似於用戶名持久化的方式對評論列表內容進行持久化,讓用戶發佈的評論在刷新頁面之後依然能夠存在。修改 src/CommentApp.jshtml

class CommentApp extends Component {
  constructor () {
    super()
    this.state = {
      comments: []
    }
  }

  componentWillMount () {
    this._loadComments()
  }

  _loadComments () {
    let comments = localStorage.getItem('comments')
    if (comments) {
      comments = JSON.parse(comments)
      this.setState({ comments })
    }
  }

  _saveComments (comments) {
    localStorage.setItem('comments', JSON.stringify(comments))
  }

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

咱們增長了 _loadComments 和 _saveComments 分別用於加載和保存評論列表數據。用戶每次提交評論都會把評論列表數據保存一次,因此咱們在 handleSubmitComment調用 _saveComments 方法;而在 componentWillMount 中調用 _loadComments 方法,在組件開始掛載的時候把評論列表數據加載出來 setState 到 this.state 當中,組件就能夠渲染從 LocalStorage 從加載出來的評論列表數據了。ui

如今發佈評論,而後刷新能夠看到咱們的評論並不會像之前同樣消失。很是的不錯,持久化評論的功能也完成了。this

顯示評論發佈時間

如今咱們給每條評論都加上發佈的日期,而且在評論列表項上顯示已經發表了多久,例如「1 秒前」、「30分鐘前」,而且會每隔 5 秒進行更新。修改 src/CommentInput.js當用戶點擊發布按鈕的時候,傳出去的評論數據帶上評論發佈的時間戳:spa

...
  handleSubmit () {
    if (this.props.onSubmit) {
      this.props.onSubmit({
        username: this.state.username,
        content: this.state.content,
        createdTime: +new Date()
      })
    }
    this.setState({ content: '' })
  }
...

在評論列表項上顯示評論,修改 src/comment.jscode

class Comment extends Component {
  static propTypes = {
    comment: PropTypes.object.isRequired
  }

  constructor () {
    super()
    this.state = { timeString: '' }
  }

  componentWillMount () {
    this._updateTimeString()
  }

  _updateTimeString () {
    const comment = this.props.comment
    const duration = (+Date.now() - comment.createdTime) / 1000
    this.setState({
      timeString: duration > 60
        ? `${Math.round(duration / 60)} 分鐘前`
        : `${Math.round(Math.max(duration, 1))} 秒前`
    })
  }

  render () {
    return (
      <div className='comment'>
        <div className='comment-user'>
          <span>{this.props.comment.username} </span>:
        </div>
        <p>{this.props.comment.content}</p>
        <span className='comment-createdtime'>
          {this.state.timeString}
        </span>
      </div>
    )
  }
}

每一個 Comment 組件實例會保存一個 timeString 狀態,用於該評論顯示發佈了多久。_updateTimeString 這個私有方法會根據 props.comment 裏面的 createdTime 來更新這個 timeString:計算當前時間和評論發佈時間的時間差,若是已經發布 60 秒以上就顯示分鐘,不然就顯示秒。而後 componentWillMount 會在組件掛載階段調用 _updateTimeString 更新一下這個字符串,render() 方法就把這個顯示時間差的字符串渲染到一個 <span> 上。component

再看看頁面顯示:htm

這時候的時間是不會自動更新的。除非你手動刷新頁面,不然永遠顯示「1 秒前」。咱們能夠在 componentWillMount 中啓動一個定時器,每隔 5 秒調用一下 _updateTimeString,讓它去經過 setState 更新 timeStringblog

...
  componentWillMount () {
    this._updateTimeString()
    this._timer = setInterval(
      this._updateTimeString.bind(this),
      5000
    )
  }
...

這樣就能夠作到評論的發佈時間自動刷新了,到這裏前 4 個需求都已經完成了。字符串

get

相關文章
相關標籤/搜索