实战分析:评论功能(八)

接下能够重构组件部分的内容了。先回顾一下以前咱们是怎么划分组件的: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

相关文章
相关标签/搜索