我正在尝试创建评论部分,其中this.state
会存储每次提交新评论时通过将旧状态与新状态组合而做出的所有评论。但是,我在我的应用程序中得到了非常奇怪的行为,我无法解释。在第一个评论提交时,该评论通过调用父函数commentForm
的回调从commentSection
发送到其父handleCommentSubmit
,以更新我的comments
状态。一切都正确呈现。但是,一旦提交第二条评论,就会进行相同的过程;状态已更新,但不包含先前的第一条评论。在此状态更新之后,新状态将发送到commentList
以呈现注释。在这种情况下,奇怪的是,传递给它的道具this.state.comments
现在包含一个数组,该数组包含第二个注释的2个(请参见屏幕快照的底部)。这导致我的评论部分现在显示用户2的评论两次,而不显示用户1的评论。有人知道为什么会这样吗?
这是相关代码:
父母:
class CommentsSection extends React.Component{
constructor(props){
super(props)
this.state={comments:[], loading:false}
}
componentDidMount(){
}
handleCommentSubmit = (newComment) =>{
var comments = this.state.comments;
var newComments = comments.concat([newComment]);
this.setState({comments: newComments},console.log('The current state is now',this.state.comments));
//comment is object with author and message. Add new comment to old comments
//this.setState({comments:[...this.state.comments,newComment]},console.log(this.state, 'state updated'))
}
//Comments are create in comment form, passed up then sent down through commentList to individual comment rendering inside comment.js
// comment form oncommentsubmit running everytime it renders, not only on submital
render(){
const loadingSpin = this.state.loading ? "App-logo Spin" : "App-logo";
return(
<div>
<span><h4> Comments </h4></span>
<div className="ui grid">
<div className = "right floated eight wide column" >
<CommentList comments={this.state.comments}/>
</div>
<div className="left floated eight wide column">
<CommentForm onCommentSubmit={this.handleCommentSubmit}/>
</div>
</div>
</div>
)
}
}
export default CommentsSection
孩子:
function CommentList ({comments}){
//need to map over array of comments to format correctly
console.log('This is what is passed as props to CommentList', comments)
comments = comments.map((comments)=>{return <Comment key = {comments.message} message={comments.message} author={comments.author} />})
return(<div>{comments}</div>)
}
export default CommentList
class CommentForm extends React.Component{
constructor(props){
super(props)
this.comment={author:'', message:''}
}
handleSubmit= (e)=>{
e.preventDefault()
var authorVal = this.comment.author;
var textVal = this.comment.message;
//this stops any comment submittal if anything missing
if (!textVal || !authorVal) {
return;
}
this.props.onCommentSubmit(this.comment);
//reset form values
e.target[0].value = '';
e.target[1].value = '';
}
handleFormChange= (e)=>{
e.preventDefault()
if(e.target.name==='author'){
var author = e.target.value.trim();
this.comment.author = author
}else if(e.target.name==='message'){
var message = e.target.value.trim();
this.comment.message = message
}
}
render() {
return (
<form className = "ui form" method="post" onChange={(e)=>{this.handleFormChange(e)}} onSubmit={(e)=>{this.handleSubmit(e)}}>
<div className="form-group">
<input
className="form-control"
placeholder="user..."
name="author"
type="text"
/>
</div>
<div className="form-group">
<textarea
className="form-control"
placeholder="comment..."
name="message"
/>
</div>
<div className="form-group">
<button disabled={null} className="btn btn-primary">
Comment ➤
</button>
</div>
</form>
);
}
}
答案 0 :(得分:0)
this.setState(prevState => ({comments: [...prevState.comments, newComment]}))
答案 1 :(得分:0)
问题。
您正在将author
和message
存储在this.comment
组件的实例变量(<CommentForm />
)上。this.comment
甚至在重新存储后仍保持相同的存储位置-渲染。因此,即使在重新渲染之后,它也是同一个对象。您只是覆盖该对象的属性。而您的父状态是一个注释数组,其中每个元素只是指向同一this.comment
对象的指针,该对象每次都会被覆盖。
查看链接,继续添加注释以查看父组件状态发生了什么 https://stackblitz.com/edit/react-cubmcf
解决方案
修改handleSubmit就像这样。
handleCommentSubmit = newComment => {
var comments = this.state.comments;
// var newComments = comments.concat([newComment]);
this.setState({
comments: [...comments, newComment]
});
};
更新注释表单以使用状态而不是实例变量。
所做的更改
class CommentForm extends React.Component {
constructor(props) {
super(props);
this.state = { author: "", message: "" };
}
handleSubmit = e => {
e.preventDefault();
const {author, message} = this.state;
//this stops any comment submittal if anything missing
if (!author || !message) {
return;
}
this.props.onCommentSubmit({ author, message });
this.setState({author: "", message : ""})
};
handleFormChange = e => {
e.preventDefault();
this.setState({[e.target.name]: e.target.value});
};
render() {
const {author, message} = this.state;
return (
<form
className="ui form"
method="post"
onChange={e => {
this.handleFormChange(e);
}}
onSubmit={e => {
this.handleSubmit(e);
}}
>
<div className="form-group">
<input
className="form-control"
placeholder="user..."
name="author"
type="text"
value = {author}
/>
</div>
<div className="form-group">
<textarea
className="form-control"
placeholder="comment..."
name="message"
value={message}
/>
</div>
<div className="form-group">
<button disabled={null} className="btn btn-primary">
Comment ➤
</button>
</div>
</form>
);
}
}