Comment评论

对网站内容的反馈、评价和讨论。

何时使用

评论组件可用于对事物的讨论,例如页面、博客文章、问题等等。

代码演示

Comment评论 - 图1

基本评论

一个基本的评论组件,带有作者、头像、时间和操作。

  1. import React, { createElement, useState } from 'react';
  2. import { Comment, Tooltip, Avatar } from 'antd';
  3. import moment from 'moment';
  4. import { DislikeOutlined, LikeOutlined, DislikeFilled, LikeFilled } from '@ant-design/icons';
  5. const Demo = () => {
  6. const [likes, setLikes] = useState(0);
  7. const [dislikes, setDislikes] = useState(0);
  8. const [action, setAction] = useState(null);
  9. const like = () => {
  10. setLikes(1);
  11. setDislikes(0);
  12. setAction('liked');
  13. };
  14. const dislike = () => {
  15. setLikes(0);
  16. setDislikes(1);
  17. setAction('disliked');
  18. };
  19. const actions = [
  20. <Tooltip key="comment-basic-like" title="Like">
  21. <span onClick={like}>
  22. {createElement(action === 'liked' ? LikeFilled : LikeOutlined)}
  23. <span className="comment-action">{likes}</span>
  24. </span>
  25. </Tooltip>,
  26. <Tooltip key="comment-basic-dislike" title="Dislike">
  27. <span onClick={dislike}>
  28. {React.createElement(action === 'disliked' ? DislikeFilled : DislikeOutlined)}
  29. <span className="comment-action">{dislikes}</span>
  30. </span>
  31. </Tooltip>,
  32. <span key="comment-basic-reply-to">Reply to</span>,
  33. ];
  34. return (
  35. <Comment
  36. actions={actions}
  37. author={<a>Han Solo</a>}
  38. avatar={
  39. <Avatar
  40. src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png"
  41. alt="Han Solo"
  42. />
  43. }
  44. content={
  45. <p>
  46. We supply a series of design principles, practical patterns and high quality design
  47. resources (Sketch and Axure), to help people create their product prototypes beautifully
  48. and efficiently.
  49. </p>
  50. }
  51. datetime={
  52. <Tooltip title={moment().format('YYYY-MM-DD HH:mm:ss')}>
  53. <span>{moment().fromNow()}</span>
  54. </Tooltip>
  55. }
  56. />
  57. );
  58. };
  59. ReactDOM.render(<Demo />, mountNode);
  1. /* tile uploaded pictures */
  2. .comment-action {
  3. padding-left: 8px;
  4. cursor: 'auto';
  5. }
  6. [class*='-col-rtl'] .comment-action {
  7. padding-right: 8px;
  8. padding-left: 0;
  9. }

Comment评论 - 图2

配合 List 组件

配合 List 组件展现评论列表。

  1. import { Comment, Tooltip, List } from 'antd';
  2. import moment from 'moment';
  3. const data = [
  4. {
  5. actions: [<span key="comment-list-reply-to-0">Reply to</span>],
  6. author: 'Han Solo',
  7. avatar: 'https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png',
  8. content: (
  9. <p>
  10. We supply a series of design principles, practical patterns and high quality design
  11. resources (Sketch and Axure), to help people create their product prototypes beautifully and
  12. efficiently.
  13. </p>
  14. ),
  15. datetime: (
  16. <Tooltip title={moment().subtract(1, 'days').format('YYYY-MM-DD HH:mm:ss')}>
  17. <span>{moment().subtract(1, 'days').fromNow()}</span>
  18. </Tooltip>
  19. ),
  20. },
  21. {
  22. actions: [<span key="comment-list-reply-to-0">Reply to</span>],
  23. author: 'Han Solo',
  24. avatar: 'https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png',
  25. content: (
  26. <p>
  27. We supply a series of design principles, practical patterns and high quality design
  28. resources (Sketch and Axure), to help people create their product prototypes beautifully and
  29. efficiently.
  30. </p>
  31. ),
  32. datetime: (
  33. <Tooltip title={moment().subtract(2, 'days').format('YYYY-MM-DD HH:mm:ss')}>
  34. <span>{moment().subtract(2, 'days').fromNow()}</span>
  35. </Tooltip>
  36. ),
  37. },
  38. ];
  39. ReactDOM.render(
  40. <List
  41. className="comment-list"
  42. header={`${data.length} replies`}
  43. itemLayout="horizontal"
  44. dataSource={data}
  45. renderItem={item => (
  46. <li>
  47. <Comment
  48. actions={item.actions}
  49. author={item.author}
  50. avatar={item.avatar}
  51. content={item.content}
  52. datetime={item.datetime}
  53. />
  54. </li>
  55. )}
  56. />,
  57. mountNode,
  58. );

Comment评论 - 图3

嵌套评论

评论可以嵌套。

  1. import { Comment, Avatar } from 'antd';
  2. const ExampleComment = ({ children }) => (
  3. <Comment
  4. actions={[<span key="comment-nested-reply-to">Reply to</span>]}
  5. author={<a>Han Solo</a>}
  6. avatar={
  7. <Avatar
  8. src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png"
  9. alt="Han Solo"
  10. />
  11. }
  12. content={
  13. <p>
  14. We supply a series of design principles, practical patterns and high quality design
  15. resources (Sketch and Axure).
  16. </p>
  17. }
  18. >
  19. {children}
  20. </Comment>
  21. );
  22. ReactDOM.render(
  23. <ExampleComment>
  24. <ExampleComment>
  25. <ExampleComment />
  26. <ExampleComment />
  27. </ExampleComment>
  28. </ExampleComment>,
  29. mountNode,
  30. );

Comment评论 - 图4

回复框

评论编辑器组件提供了相同样式的封装以支持自定义评论编辑器。

  1. import { Comment, Avatar, Form, Button, List, Input } from 'antd';
  2. import moment from 'moment';
  3. const { TextArea } = Input;
  4. const CommentList = ({ comments }) => (
  5. <List
  6. dataSource={comments}
  7. header={`${comments.length} ${comments.length > 1 ? 'replies' : 'reply'}`}
  8. itemLayout="horizontal"
  9. renderItem={props => <Comment {...props} />}
  10. />
  11. );
  12. const Editor = ({ onChange, onSubmit, submitting, value }) => (
  13. <>
  14. <Form.Item>
  15. <TextArea rows={4} onChange={onChange} value={value} />
  16. </Form.Item>
  17. <Form.Item>
  18. <Button htmlType="submit" loading={submitting} onClick={onSubmit} type="primary">
  19. Add Comment
  20. </Button>
  21. </Form.Item>
  22. </>
  23. );
  24. class App extends React.Component {
  25. state = {
  26. comments: [],
  27. submitting: false,
  28. value: '',
  29. };
  30. handleSubmit = () => {
  31. if (!this.state.value) {
  32. return;
  33. }
  34. this.setState({
  35. submitting: true,
  36. });
  37. setTimeout(() => {
  38. this.setState({
  39. submitting: false,
  40. value: '',
  41. comments: [
  42. {
  43. author: 'Han Solo',
  44. avatar: 'https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png',
  45. content: <p>{this.state.value}</p>,
  46. datetime: moment().fromNow(),
  47. },
  48. ...this.state.comments,
  49. ],
  50. });
  51. }, 1000);
  52. };
  53. handleChange = e => {
  54. this.setState({
  55. value: e.target.value,
  56. });
  57. };
  58. render() {
  59. const { comments, submitting, value } = this.state;
  60. return (
  61. <>
  62. {comments.length > 0 && <CommentList comments={comments} />}
  63. <Comment
  64. avatar={
  65. <Avatar
  66. src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png"
  67. alt="Han Solo"
  68. />
  69. }
  70. content={
  71. <Editor
  72. onChange={this.handleChange}
  73. onSubmit={this.handleSubmit}
  74. submitting={submitting}
  75. value={value}
  76. />
  77. }
  78. />
  79. </>
  80. );
  81. }
  82. }
  83. ReactDOM.render(<App />, mountNode);

API

参数说明类型默认值版本
actions在评论内容下面呈现的操作项列表Array<ReactNode>-
author要显示为注释作者的元素ReactNode-
avatar要显示为评论头像的元素 - 通常是 antd Avatar 或者 srcReactNode-
children嵌套注释应作为注释的子项提供ReactNode-
content评论的主要内容ReactNode-
datetime展示时间描述ReactNode-