CommentBox是顶层组件,里面包含 CommentList 和 CommentForm组件;CommentList里又有若干Comment组件。
这里我们采用 create-react-app 快速脚手架 安装,具体安装方式请见:
React安装及目录结构(启动项目方式也在其中)
组件:CommentBox、CommentList、Comment、CommentForm
分别对应一个js文件~
import React from 'react';
import ReactDOM from 'react-dom';
import CommentBox from './CommentBox';
import './index.css';
let data = [
{author:'bty',content:'悟空的自在极意功是真的厉害!!',date:'2019/2/1 下午4:00:05'},
{author:'oppen',content:'世上只有妈妈好?爸爸呢?',date:'2019/2/1 下午3:04:05'}
];
ReactDOM.render(
,
document.getElementById('root')
);
./src/CommentBox.js
import React, { Component } from 'react';
import CommentList from './CommentList';
import CommentForm from './CommentForm';
class CommentBox extends Component {
constructor(props) {
super(props);
this.state = {
data: this.props.data,
editToggle: Array(this.props.data.length).fill(false),
};
}
handleCommentSubmit(comment) {
this.setState({
data: this.state.data.concat([comment]),
});
}
handleCommentDelete(index) {
const data = this.state.data.slice(0),
editToggle = this.state.editToggle.slice(0);
data.splice(index, 1);
editToggle.splice(index, 1);
this.setState({
data: data,
editToggle: editToggle,
});
}
handleEditToggle(index) {
const editToggle = this.state.editToggle.slice(0);
editToggle[index] = !editToggle[index];
this.setState({
editToggle: editToggle,
});
}
handleCommentUpdate(index, comment) {
const data = this.state.data.slice(0),
editToggle = this.state.editToggle.slice(0);
data[index] = comment;
editToggle[index] = !editToggle[index];
this.setState({
data: data,
editToggle: editToggle,
});
}
render() {
return (
评论
this.handleEditToggle(index)}
handleCommentDelete={(index) => this.handleCommentDelete(index)}
handleCommentUpdate={(index, comment) => this.handleCommentUpdate(index, comment)}
/>
this.handleCommentSubmit(comment)}/>
);
}
}
export default CommentBox;
./src/CommentList.js
import React from 'react';
import Comment from './Comment';
function CommentList(props) {
let comments = props.data.map((item, index) => {
item.index = index;
return (
props.handleEditToggle(index)}
handleCommentDelete={() => props.handleCommentDelete(index)}
handleCommentUpdate={props.handleCommentUpdate}
/>
);
});
return (
{comments}
);
}
export default CommentList;
./src/Comment.js
import React, { Component } from 'react';
class Comment extends Component {
handleSubmitUpdate(e) {
e.preventDefault();
let author = this.props.author,
content = this.refs.content.value,
date = this.props.date;
this.props.handleCommentUpdate(this.props.index, {author, content, date});
}
render() {
let {content, author, date, editToggle} = {...this.props},
editButton = editToggle ? '取消' : '编辑',
contentDiv = editToggle ?
:
{content};
return (
{contentDiv}
);
}
}
export default Comment;
./src/CommentForm.js
import React, { Component } from 'react';
class CommentForm extends Component {
handleSubmit(e) {
e.preventDefault();
let content = this.refs.content.value,
author = this.refs.author.value,
date = new Date().toLocaleString(),
warning = this.refs.warning;
if(!author) {
warning.innerHTML = '* 姓名不能为空';
return null;
}else if(!content) {
warning.innerHTML = '* 评论不能为空';
return null;
}else {
warning.innerHTML = '';
}
this.props.handleCommentSubmit({content, author, date});
}
render() {
return (
);
}
}
export default CommentForm;
./src/index.css:
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-size: 12px;
}
a {
text-decoration: none;
}
.comment-box {
width: 80%;
border: 1px solid #ccc;
border-radius: 3px;
margin: 15px;
padding: 30px;
}
.title,
.comment,
.metadata,
.submitform {
width: 100%;
}
.title {
border-bottom: 1px solid #ccc;
padding-bottom: 10px;
color: #B8860B;
font-size: 16px;
}
.comment {
background: #F8F8FF;
margin-top: 20px;
padding: 20px 20px 14px 20px;
}
.comment .content {
width: 100%;
font-size: 15px;
color: #333;
}
.metadata{
margin-top: 10px;
}
.metadata .author,
.metadata .date,
.metadata .option{
display: inline-block;
color: #A9A9A9;
}
.metadata .author,
.metadata .date {
margin-right: 30px;
}
.metadata .option {
margin-right: 6px;
}
.metadata .option:hover{
text-decoration: underline;
}
.submitform {
margin-top: 20px;
}
.editContent textarea{
width:88%;
min-height: 50px;
border-radius: 3px;
border: 1px solid #ccc;
padding: 5px 10px;
}
.editContent button {
width: 40px;
height: 40px;
border-radius: 50%;
border: 1px solid #97CBFF;
background: #97CBFF;
color: #fff;
position: relative;
left: 20px;
top:-19px;
}
.editContent button:hover{
cursor: pointer;
background: #FF5151;
border: 1px solid #FF5151;
}
.warning {
color: red;
}
.form-row {
padding: 10px 0;
}
.form-row input[type='text'],
.form-row button,
.form-row textarea {
border-radius: 2px;
}
.form-row input[type='text'],
.form-row textarea {
width: 50%;
border: 1px solid #ccc;
padding: 8px 10px;
}
.form-row textarea {
min-height: 100px;
}
.form-row button {
padding: 6px;
width: 80px;
background: #97CBFF;
border: 1px solid #97CBFF;
color: #fff;
font-size: 13px;
}
.form-row button:hover {
cursor: pointer;
}