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

接下能夠重構組件部分的內容了。先回顧一下以前咱們是怎麼劃分組件的:html

組件樹:react

這樣劃分方式固然是沒錯的。可是在組件的實現上有些問題,咱們以前並無太多地考慮複用性問題。因此如今能夠看看 comment-app2 的 CommentInput 組件,你會發現它裏面有一些 LocalStorage 操做:服務器

 

...
  _loadUsername () {
    const username = localStorage.getItem('username')
    if (username) {
      this.setState({ username })
    }
  }

  _saveUsername (username) {
    localStorage.setItem('username', username)
  }

  handleUsernameBlur (event) {
    this._saveUsername(event.target.value)
  }

  handleUsernameChange (event) {
    this.setState({
      username: event.target.value
    })
  }
...

它是一個依賴 LocalStorage 數據的 Smart 組件。若是別的地方想使用這個組件,可是數據卻不是從 LocalStorage 裏面取的,而是從服務器取的,那麼這個組件就無法複用了。app

因此如今須要從複用性角度從新思考如何實現和組織這些組件。假定在目前的場景下,CommentInputCommentListComment 組件都是須要複用的,咱們就要把它們作成 Dumb 組件。this

幸運的是,咱們發現其實 CommentList 和 Comment 原本就是 Dumb 組件,直接把它們倆移動到 components 目錄下便可。而 CommentInput 就須要好好重構一下了。咱們把它裏面和 LocalStorage 操做相關的代碼所有刪除,讓它從 props 獲取數據,變成一個 Dumb 組件,而後移動到 src/components/CommentInput.js 文件內:spa

import React, { Component } from 'react'
import PropTypes from 'prop-types'

export default class CommentInput extends Component {
  static propTypes = {
    username: PropTypes.any,
    onSubmit: PropTypes.func,
    onUserNameInputBlur: PropTypes.func
  }

  static defaultProps = {
    username: ''
  }

  constructor (props) {
    super(props)
    this.state = {
      username: props.username, // 從 props 上取 username 字段
      content: ''
    }
  }

  componentDidMount () {
    this.textarea.focus()
  }

  handleUsernameBlur (event) {
    if (this.props.onUserNameInputBlur) {
      this.props.onUserNameInputBlur(event.target.value)
    }
  }

  handleUsernameChange (event) {
    this.setState({
      username: event.target.value
    })
  }

  handleContentChange (event) {
    this.setState({
      content: event.target.value
    })
  }

  handleSubmit () {
    if (this.props.onSubmit) {
      this.props.onSubmit({
        username: this.state.username,
        content: this.state.content,
        createdTime: +new Date()
      })
    }
    this.setState({ content: '' })
  }
  
  render () {
     // render 方法保持不變
     // ...
  }
}

其實改動很少。原來 CommentInput 須要從 LocalStorage 中獲取 username 字段,如今讓它從 props 裏面去取;而原來用戶名的輸入框 blur 的時候須要保存 username 到 LocalStorage 的行爲也經過 props.onUserNameInputBlur 傳遞到上層去作。如今 CommentInput 是一個 Dumb 組件了,它的全部渲染操做都只依賴於 props來完成。3d

如今三個 Dumb 組件 CommentInputCommentListComment 都已經就位了。可是單靠 Dumb 組件是沒辦法完成應用邏輯的,因此接下來咱們要構建 Smart 組件來帶領它們完成任務。code

component

htm

相關文章
相關標籤/搜索