第一个react.js程序:create and show comment
import React, { Component } from "react";
import { render } from "react-dom";
import PropTypes from "prop-types";
const node = document.getElementById("root");
const data = {
post: {
id: 123,
content:
"What we hope ever to do with ease, we must first learn to do with diligence. — Samuel Johnson",
user: "Mark Thomas"
},
comments: [
{
id: 0,
user: "David",
content: "such. win."
},
{
id: 1,
user: "Haley",
content: "Love it."
},
{
id: 2,
user: "Peter",
content: "Who was Samuel Johnson?"
},
{
id: 3,
user: "Mitchell",
content: "@Peter get off Letters and do your homework"
},
{
id: 4,
user: "Peter",
content: "@mitchell ok :P"
}
]
};
class Post extends Component {
constructor(props) {
super(props);
}
render() {
return React.createElement(
"div",
{
className: "post"
},
React.createElement(
"h2",
{
className: "postAuthor",
id: this.props.id
},
this.props.user,
React.createElement(
"span",
{
className: "postBody"
},
this.props.content
),
this.props.children
)
);
}
}
Post.propTypes = {
user: PropTypes.string.isRequired,
content: PropTypes.string.isRequired,
id: PropTypes.number.isRequired
};
class Comment extends Component {
constructor(props) {
super(props);
}
render() {
return React.createElement(
"div",
{
className: "comment"
},
React.createElement(
"h2",
{
className: "commentAuthor"
},
this.props.user,
React.createElement(
"span",
{
className: "commentContent"
},
this.props.content
)
)
);
}
}
Comment.propTypes = {
id: PropTypes.number.isRequired,
content: PropTypes.string.isRequired,
user: PropTypes.string.isRequired
};
class CreateComment extends Component {
constructor(props) {
super(props);
this.state = {
content: "",
user: ""
};
this.handleUserChange = this.handleUserChange.bind(this);
this.handleTextChange = this.handleTextChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleUserChange(event) {
const val = event.target.value;
this.setState(() => ({
user: val
}));
}
handleTextChange(event) {
const val = event.target.value;
this.setState({
content: val
});
}
handleSubmit(event) {
event.preventDefault();
this.props.onCommentSubmit({
user: this.state.user.trim(),
content: this.state.content.trim()
});
this.setState(() => ({
user: "",
content: ""
}));
}
render() {
return React.createElement(
"form",
{
className: "createComment",
onSubmit: this.handleSubmit
},
React.createElement("input", {
type: "text",
placeholder: "Your name",
value: this.state.user,
onChange: this.handleUserChange
}),
React.createElement("input", {
type: "text",
placeholder: "Thoughts?",
value: this.state.content,
onChange: this.handleTextChange
}),
React.createElement("input", {
type: "submit",
value: "Post"
})
);
}
}
CreateComment.propTypes = {
onCommentSubmit: PropTypes.func.isRequired,
content: PropTypes.string
};
class CommentBox extends Component {
constructor(props) {
super(props);
this.state = {
comments: this.props.comments
};
this.handleCommentSubmit = this.handleCommentSubmit.bind(this);
}
handleCommentSubmit(comment) {
const comments = this.state.comments;
comment.id = Date.now();
const newComments = comments.concat([comment]);
this.setState({
comments: newComments
});
}
render() {
return React.createElement(
"div",
{
className: "commentBox"
},
React.createElement(Post, {
id: this.props.post.id,
content: this.props.post.content,
user: this.props.post.user
}),
this.state.comments.map(function(comment) {
return React.createElement(Comment, {
key: comment.id,
id: comment.id,
content: comment.content,
user: comment.user
});
}),
React.createElement(CreateComment, {
onCommentSubmit: this.handleCommentSubmit
})
);
}
}
CommentBox.propTypes = {
post: PropTypes.object,
comments: PropTypes.arrayOf(PropTypes.object)
};
render(
React.createElement(CommentBox, {
comments: data.comments,
post: data.post
}),
node
);
在线code:https://codesandbox.io/s/z6o64oljn4?file=/index.js:0-4834
摘抄自:Minning React In Action 书中 P52页
- Post的component比较简单,就是现实文章post内容。Comment组件也是简单的现实comment内容。两个组件都不涉及state数据。
- CreateComment组件包括了用户输入评论内容部分,有一个state:包含用户名和内容的数据,其中点击了submit按钮后,就调用函数:handleSubmit,而这个函数其实是调用了通过prop传过来的父组件prop中的onCommentSubmit函数,这样就把本组件中的state数据传给父组件了。
- CommentBox 是个复合组件,其child包括了post,多个comment和一个CreateComment组件。它的state是comment组件的数组comments,又定义了handleCommentSubmit函数,该函数通过给CreateComment组件的prop中给了子组件,handleCommentSubmit的作用是把从CreateComment组件搜集到的数据添加到自己state中的comments数组中,而其child组件中用到了.map()函数来把state中的comments数组组成一个Comment组件数组。
- render方法最后只render渲染CommentBox组件。
其中关于code中的.bind()函数,对于JS新手来说比较迷惑,如果缺少了这个程序就不工作了。关于bind方法 see: https://www.javascripttutorial.net/javascript-bind/#:~:text=The%20bind%20%28%29%20method%20creates%20a%20new%20function%2C,This%20is%20known%20as%20function%20borrowing%20in%20JavaScript.
https://www.w3schools.com/js/js_function_bind.asp
下面是用JSX写的同一程序:https://codesandbox.io/s/vnwz6y28x5?file=/index.js
import React, { Component } from "react";
import { render } from "react-dom";
import PropTypes from "prop-types";
const node = document.getElementById("root");
const data = {
post: {
id: 123,
content:
"What we hope ever to do with ease, we must first learn to do with diligence. — Samuel Johnson",
user: "Mark Thomas"
},
comments: [
{
id: 0,
user: "David",
content: "such. win."
},
{
id: 1,
user: "Haley",
content: "Love it."
},
{
id: 2,
user: "Peter",
content: "Who was Samuel Johnson?"
},
{
id: 3,
user: "Mitchell",
content: "@Peter get off Letters and do your homework"
},
{
id: 4,
user: "Peter",
content: "@mitchell ok :P"
}
]
};
class Post extends Component {
render() {
return (
<div className="post">
<h2 className="postAuthor">{this.props.user}</h2>
<span className="postBody">{this.props.content}</span>
{this.props.children}
</div>
);
}
}
Post.propTypes = {
user: PropTypes.string.isRequired,
content: PropTypes.string.isRequired,
id: PropTypes.number.isRequired
};
class Comment extends Component {
render() {
return (
<div className="comment">
<h2 className="commentAuthor">{this.props.user + " : "}</h2>
<span className="commentContent">{this.props.content}</span>
</div>
);
}
}
Comment.propTypes = {
id: PropTypes.number.isRequired,
content: PropTypes.string.isRequired,
user: PropTypes.string.isRequired
};
class CreateComment extends Component {
constructor(props) {
super(props);
this.state = {
content: "",
user: ""
};
this.handleUserChange = this.handleUserChange.bind(this);
this.handleTextChange = this.handleTextChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleUserChange(event) {
this.setState({
user: event.target.value
});
}
handleTextChange(event) {
this.setState({
content: event.target.value
});
}
handleSubmit(event) {
event.preventDefault();
this.props.onCommentSubmit({
user: this.state.user.trim(),
content: this.state.content.trim()
});
this.setState({
user: "",
content: ""
});
}
render() {
return (
<form onSubmit={this.handleSubmit} className="createComment">
<input
value={this.state.user}
onChange={this.handleUserChange}
placeholder="Your name"
type="text"
/>
<input
value={this.state.content}
onChange={this.handleTextChange}
placeholder="Thoughts?"
type="text"
/>
<button type="submit">Post</button>
</form>
);
}
}
class CommentBox extends Component {
constructor(props) {
super(props);
this.state = {
comments: this.props.comments
};
this.handleCommentSubmit = this.handleCommentSubmit.bind(this);
}
handleCommentSubmit(comment) {
const comments = this.state.comments;
comment.id = Date.now();
const newComments = comments.concat([comment]);
this.setState({
comments: newComments
});
}
render() {
return (
<div className="commentBox">
<Post
id={this.props.post.id}
content={this.props.post.content}
user={this.props.post.user}
/>
{this.state.comments.map(function(comment) {
return (
<Comment
key={comment.id}
content={comment.content}
user={comment.user}
/>
);
})}
<CreateComment onCommentSubmit={this.handleCommentSubmit} />
</div>
);
}
}
CommentBox.propTypes = {
post: PropTypes.object,
comments: PropTypes.arrayOf(PropTypes.object)
};
render(<CommentBox comments={data.comments} post={data.post} />, node);

浙公网安备 33010602011771号