我还在学习ReactJS的状态和生命周期,并遇到了一个场景,我提交的表单应该保存表单值,然后将返回的JSON对象追加到数组的末尾渲染存储原始数组的组件。
使用我当前的设置,我有组件设置和表单提交与返回的JSON对象,但状态包含一个空数组而不是对象传播{...comment}
,它看起来不像setState正在更新组件,但这可能是由于前面提到的空数组。有人能指出我正确的方向吗?
注释:
import React from 'react';
import fetch from 'node-fetch';
//record Comment - Comment Form Handle POST
class CommentForm extends React.Component {
constructor(props){
super(props);
this.state = {
value: '',
comments: []
};
this.onChange = this.onChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
postComment(comment, recordId, csrfToken) {
var body = { comment: comment };
var route = 'http://localhost:3000/record/' + recordId + '/comment';
fetch(route,
{
method: 'POST',
body: JSON.stringify(body),
headers: {
'X-CSRF-Token': csrfToken,
'Accept': 'application/json',
'Content-Type': 'application/json'
}
})
.then(res => {
return res.json();
})
.then(data => {
console.log(data);
let commentsArr = this.state.comments;
this.setState({comments: commentsArr.concat(data)});
})
.catch(err => {
console.log(err);
});
}
onChange(e){
this.setState({
value: e.target.value
});
}
handleSubmit(e){
e.preventDefault();
this.postComment(this.state.value, this.props.recordId, this.props.csrf);
}
render(){
return (
<div className="record-comment__form">
<div className="row">
<form action={"/record/" + this.props.recordId + "/comment"} method="post" onSubmit={this.handleSubmit}>
<input type="hidden" name="_csrf" value={this.props.csrf}/>
<textarea name="comment" className="record-comment__form-text-area" onChange={e => this.setState({ value: e.target.value })} value={this.state.value}></textarea>
<button type="submit" className="record-comment__form-button" disabled={!this.state.value}>Comment</button>
</form>
</div>
</div>
)
}
}
//record Comment - Comment
const Comment = props => {
return (
<div className="row">
<div className="col-md-12">
<h5>{props.user_id}</h5>
<h4>{props.comment}</h4>
<h3>{props.synotate_user.fullNameSlug}</h3>
</div>
</div>
)
}
//record Comment - Container
export default class Comments extends React.Component {
render() {
return (
<div className="record-comment-container">
<CommentForm recordId={this.props.recordId} csrf={this.props.csrf}/>
{ this.props.record_comments.map((comment, i) =>
<Comment {...comment} key={this.props.recordCommentId}/>
)}
</div>
);
}
}
记录(父组件)(正在设置评论的位置):
//GET /api/test and set to state
class RecordFeedContainer extends React.Component{
constructor(props, context) {
super(props, context);
this.state = this.context.data || window.__INITIAL_STATE__ || {records: []};
}
fetchList() {
fetch('http://localhost:3000/api/test')
.then(res => {
return res.json();
})
.then(data => {
console.log(data);
this.setState({ records: data.record, user: data.user, csrf: data.csrfToken });
})
.catch(err => {
console.log(err);
});
}
componentDidMount() {
this.fetchList();
}
render() {
return (
<div className="container">
<h2>Comments List</h2>
<RecordFeed {...this.state} />
</div>
)
}
};
//Loop through JSON and create Record and Comment Container Component
const RecordFeed = props => {
return (
<div>
{
props.records.map((record, index) => {
return (
<div className="row">
<div className="col-md-6 col-md-offset-3 record-card">
<RecordCard {...record} key={record.recordIdHash} user={props.user} />
<Comments {...record} key={index} recordId={record.recordIdHash} csrf={props.csrf}/>
</div>
</div>
);
})
}
</div>
)
}
答案 0 :(得分:2)
您的问题是,在呈现<Comments>
时,this.props.record_comments
不是您在<CommentForm>
组件状态下更新的评论。每个组件都有自己的内部状态。
您需要将状态传递给<Comments>
组件。您需要将状态移至顶层或使用状态管理系统,如Redux,这将允许您访问可能包含注释数组的共享状态。
从顶级组件中,您可以管理其中的状态,如下所示:
this.state = {
comments: [],
// other shared state
};
您可以将更新注释函数(例如updateCommentsFunc()
命名)传递给<CommentForm>
,如下所示:
<CommentForm updateComments={this.updateCommentsFunc} recordId={this.props.recordId} csrf={this.props.csrf}/>
这将允许您通过以下内容将更新的注释传递回父组件:
const updateCommentsFunc = (newComments) => {
this.setState({comments: [...this.state.comments, newComments]});
}
答案 1 :(得分:0)
您的postComment()
功能似乎未正确绑定到您的<CommentForm/>
组件的this
。结果是;从函数中调用this.setState()
并没有真正做任何事情。
尝试在构造函数方法中绑定它。
constructor(props) {
// ...
this.postComment = this.postComment.bind(this)
}
postComment = (comment, recordId, csrfToken) => {
// ...
}
有关React绑定模式的详细信息,请参阅arrow function。