资讯专栏INFORMATION COLUMN

React.js 小书 Lesson27 - 实战分析:评论功能(六)

Freeman / 603人阅读

摘要:所以我们给评论组件加上删除评论的功能,这样就可以删除不想要的评论了。输入这是代码块,这是正常内容。到目前为止,第二阶段的实战已经全部完成,你可以在这里找到完整的代码。下一节中我们将介绍小书高阶组件。

React.js 小书 Lesson27 - 实战分析:评论功能(六)

本文作者:胡子大哈
本文原文:http://huziketang.com/books/react/lesson27

转载请注明出处,保留原文链接以及作者信息

在线阅读:http://huziketang.com/books/react

{%raw%}

删除评论

现在发布评论,评论不会消失,评论越来越多并不是什么好事。所以我们给评论组件加上删除评论的功能,这样就可以删除不想要的评论了。修改 src/Comment.jsrender 方法,新增一个删除按钮:

...
  render () {
    const { comment } = this.props
    return (
      
{comment.username}

{comment.content}

{this.state.timeString} 删除
) } ...

我们在后面加了一个删除按钮,因为 index.css 定义了样式,所以鼠标放到特定的评论上才会显示删除按钮,让用户体验好一些。

我们知道评论列表数据是放在 CommentApp 当中的,而这个删除按钮是在 Comment 当中的,现在我们要做的事情是用户点击某条评论的删除按钮,然后在 CommentApp 中把相应的数据删除。但是 CommentAppComment 的关系是这样的:

CommentCommentApp 之间隔了一个 CommentListComment 无法直接跟 CommentApp 打交道,只能通过 CommentList 来转发这种删除评论的消息。修改 Comment 组件,让它可以把删除的消息传递到上一层:

class Comment extends Component {
  static propTypes = {
    comment: PropTypes.object.isRequired,
    onDeleteComment: PropTypes.func,
    index: PropTypes.number
  }
...
  handleDeleteComment () {
    if (this.props.onDeleteComment) {
      this.props.onDeleteComment(this.props.index)
    }
  }

  render () {
    ...
        
          删除
        
      
) }

现在在使用 Comment 的时候,可以传入 onDeleteCommentindex 两个参数。index 用来标志这个评论在列表的下标,这样点击删除按钮的时候我们才能知道你点击的是哪个评论,才能知道怎么从列表数据中删除。用户点击删除会调用 handleDeleteComment ,它会调用从上层传入的 props. onDeleteComment 函数告知上一层组件删除的消息,并且把评论下标传出去。现在修改 src/CommentList.js 让它把这两个参数传进来:

class CommentList extends Component {
  static propTypes = {
    comments: PropTypes.array,
    onDeleteComment: PropTypes.func
  }

  static defaultProps = {
    comments: []
  }

  handleDeleteComment (index) {
    if (this.props.onDeleteComment) {
      this.props.onDeleteComment(index)
    }
  }

  render() {
    return (
      
{this.props.comments.map((comment, i) => )}
) } }

当用户点击按钮的时候,Comment 组件会调用 props.onDeleteComment,也就是 CommentListhandleDeleteComment 方法。而 handleDeleteComment 会调用 CommentList 所接受的配置参数中的 props.onDeleteComment,并且把下标传出去。

也就是说,我们可以在 CommentAppCommentList 传入一个 onDeleteComment 的配置参数来接受这个删除评论的消息,修改 CommentApp.js

...
  handleDeleteComment (index) {
    console.log(index)
  }

  render() {
    return (
      
) } } ...

现在点击删除按钮,可以在控制台看到评论对应的下标打印了出来。其实这就是这么一个过程:CommentList 把下标 index 传给 Comment。点击删除按钮的时候,Commentindex 传给了 CommentListCommentList 再把它传给 CommentApp。现在可以在 CommentApp 中删除评论了:

...
  handleDeleteComment (index) {
    const comments = this.state.comments
    comments.splice(index, 1)
    this.setState({ comments })
    this._saveComments(comments)
  }
...

我们通过 comments.splice 删除特定下标的评论,并且通过 setState 重新渲染整个评论列表;当然了,还需要把最新的评论列表数据更新到 LocalStorage 中,所以我们在删除、更新以后调用了 _saveComments 方法把数据同步到 LocalStorage 中。

现在就可以愉快地删除评论了。但是,你删除评论以后 5 秒钟后就会在控制台中看到报错了:

这是因为我们忘了清除评论的定时器,修改 src/Comment.js,新增生命周期 commentWillUnmount 在评论组件销毁的时候清除定时器:

...
  componentWillUnmount () {
    clearInterval(this._timer)
  }
...

这才算完成了第 5 个需求。

显示代码块

用户在的输入内容中任何以 `` 包含的内容都会用 包含起来显示到页面上。 这是一个 HTML 结构,需要往页面动态插入 HTML 结构我们只能用 dangerouslySetInnerHTML 了,修改 src/Comment.js,把原来 render() 函数中的:

{comment.content}

修改成:

我们把经过 this._getProcessedContent 处理的评论内容以 HTML 的方式插入到

元素中,this._getProcessedContent 是这样实现的:

...
  _getProcessedContent (content) {
    return content
      .replace(/&/g, "&")
      .replace(//g, ">")
      .replace(/"/g, """)
      .replace(/"/g, "'")
      .replace(/`([Ss]+?)`/g, "$1")
  }
...

看起来很复杂,其实前 5 行是用来处理 HTML 内容转义的,最后一行是用来插入 标签的。如果我们把用户输入的内容全部以 HTML 显示到页面上,那么就会造成跨站脚本攻击。所以前 5 个 replace 实际上是把类似于 <> 这种内容替换转义一下。而最后一行才是真正实现需求的代码,把 `` 包含的内容用 包裹起来。

输入:

这是代码块 `console.log`,这是

正常内容

看看效果:

我们安全地完成了第 6 个需求。到目前为止,第二阶段的实战已经全部完成,你可以在这里找到完整的代码。

总结

到这里第二阶段已经全部结束,我们已经掌握了全部 React.js 实战需要的入门知识。接下来我们会学习两个相对比较高级的 React.js 的概念,然后进入 React-router 和 Redux 的世界,让它们配合 React.js 来构建更成熟的前端页面。
{%endraw%}

下一节中我们将介绍《React.js 小书 Lesson28 - 高阶组件(Higher-Order Components)》。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/89676.html

相关文章

  • 写一本关于 React.js小书

    摘要:因为工作中一直在使用,也一直以来想总结一下自己关于的一些知识经验。于是把一些想法慢慢整理书写下来,做成一本开源免费专业简单的入门级别的小书,提供给社区。本书的后续可能会做成视频版本,敬请期待。本作品采用署名禁止演绎国际许可协议进行许可 React.js 小书 本文作者:胡子大哈本文原文:React.js 小书 转载请注明出处,保留原文链接以及作者信息 在线阅读:http://huzi...

    Scorpion 评论0 收藏0
  • React.js 小书 Lesson26 - 实战分析评论功能(五)

    摘要:修改请输入用户名请输入评论内容我们增加了和分别用于加载和保存评论列表数据。现在发布评论,然后刷新可以看到我们的评论并不会像以前一样消失。非常的不错,持久化评论的功能也完成了。下一节中我们将介绍小书实战分析评论功能六。 React.js 小书 Lesson26 - 实战分析:评论功能(五) 本文作者:胡子大哈本文原文:http://huziketang.com/books/react/...

    Nekron 评论0 收藏0
  • React.js 小书 Lesson16 - 实战分析评论功能(三)

    摘要:但是给传递的评论数据并没有传递给,所以现在发表评论时没有反应的。包括实现功能之前先理解分析需求,划分组件。到此为止,小书的第一阶段已经结束,你可以利用这些知识点来构建简单的功能模块了。 React.js 小书 Lesson16 - 实战分析:评论功能(三) 本文作者:胡子大哈本文原文:http://huziketang.com/books/react/lesson16 转载请注明出处...

    Gilbertat 评论0 收藏0
  • React.js 小书 Lesson14 - 实战分析评论功能(一)

    摘要:对于上面这个评论功能,可以粗略地划分成以下几部分评论功能的整体用一个叫的组件包含起来。每个评论列表项由独立的组件负责显示,这个组件被所使用。下一节中我们将介绍小书实战分析评论功能二。 React.js 小书 Lesson14 - 实战分析:评论功能(一) 本文作者:胡子大哈本文原文:http://react.huziketang.com/blog/lesson14 转载请注明出处,保...

    QiuyueZhong 评论0 收藏0
  • React.js 小书 Lesson15 - 实战分析评论功能(二)

    摘要:例如,上面设置了的为,在中被初始化为空字符串。如何向传递的数据父组件只需要通过给子组件传入一个回调函数。当用户点击发布按钮的时候,调用中的回调函数并且将传入该函数即可。下一节中我们将介绍小书实战分析评论功能三。 React.js 小书 Lesson15 - 实战分析:评论功能(二) 本文作者:胡子大哈本文原文:http://huziketang.com/books/react/les...

    siberiawolf 评论0 收藏0

发表评论

0条评论

Freeman

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<