我仍然试图处理父子数据共享,并且遇到一个问题,我的有状态组件有一组对象,可以通过componentWillReceiveProps()
在我的子道具组件中正确显示,但当我触发我的时候updateCommentsFunc()
函数,由子组件表单触发,调用POST并将值附加到数组,但是我的子组件出现undefined
错误,表明数据不是流动的状态更新。
我使用了错误的方法吗?我应该向updateCommentsFunc()
添加内容吗?
以下是控制台错误:
Uncaught TypeError: Cannot read property 'picture' of undefined
at Comment (comment.js?2fa6:15)
at mountIndeterminateComponent (react-dom.development.js?cada:10400)
at beginWork (react-dom.development.js?cada:10601)
at performUnitOfWork (react-dom.development.js?cada:12573)
at workLoop (react-dom.development.js?cada:12682)
at HTMLUnknownElement.callCallback (react-dom.development.js?cada:1299)
at Object.invokeGuardedCallbackDev (react-dom.development.js?cada:1338)
at invokeGuardedCallback (react-dom.development.js?cada:1195)
at performWork (react-dom.development.js?cada:12800)
at scheduleUpdateImpl (react-dom.development.js?cada:13185)
在行触发:
<img src={props.user.picture} className="comment__record-profile"/>
这是父组件,它被赋予一个对象,该对象的嵌套数组被映射并存储在状态数组中:
//Loop through JSON and create Comment and Comment Container Component
class CommentFeed extends React.Component {
constructor(props){
super(props);
this.state = {
comments: []
};
this.updateCommentsFunc = this.updateCommentsFunc.bind(this);
}
//Load Array to component
componentWillReceiveProps(nextProps){
let commentArr = [];
nextProps.comments.map((comment) => {
comment.comment_comments.map((comment) => {
commentArr.push(comment);
})
})
this.setState({comments: commentArr});
}
//Append new POST value to commentArr
updateCommentsFunc(newComments){
var updatedCommentArr = this.state.comments.slice();
updatedCommentArr.push(newComments)
this.setState({comments: updatedCommentArr});
}
render(){
return (
<div>
{
this.props.comments.map((comment, index) => {
return (
<div className="row">
<div className="col-md-6 col-md-offset-3 comment-card">
<CommentCard {...comment} key={comment.commentIdHash} user={this.props.user} />
<Comments comments={this.state.comments} key={index} commentId={comment.commentIdHash} csrf={this.props.csrf} updateComments={this.updateCommentsFunc}/>
</div>
</div>
);
})
}
</div>
);
}
}
这是将子组件拆分为表单并显示注释:
//Blog Comment - Container
export default class Comments extends React.Component {
render() {
return (
<div className="blog-comment-container">
<CommentForm updateComments={this.props.updateComments} blogId={this.props.blogId} csrf={this.props.csrf}/>
{ this.props.comments.map((comment, i) =>
<AttachedComment commentObj={comment} blogComponentId={this.props.blogId}/>
)}
</div>
);
}
}
以下是使用POST返回的JSON数据调用this.props.updateComments()
的表单:
class CommentForm extends React.Component {
constructor(props){
super(props);
this.state = {
value: ''
};
this.postComment = this.postComment.bind(this);
this.onChange = this.onChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
postComment(comment, blogId, csrfToken) {
var body = { comment: comment };
var route = 'http://localhost:3000/app/blog/' + blogId + '/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 => {
this.props.updateComments(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.blogId, this.props.csrf);
}
render(){
return (
<div className="blog-comment__form">
<div className="row">
<div className="col-md-12">
<label>Comment:</label>
</div>
</div>
<div className="row">
<form action={"/app/blog/" + this.props.blogId + "/comment"} method="post" onSubmit={this.handleSubmit}>
<input type="hidden" name="_csrf" value={this.props.csrf}/>
<div className="col-md-9">
<textarea name="comment" className="blog-comment__form-text-area" onChange={e => this.setState({ value: e.target.value })} value={this.state.value}></textarea>
</div>
<div className="col-md-3">
<button type="submit" className="blog-comment__form-button" disabled={!this.state.value}>Comment</button>
</div>
</form>
</div>
</div>
)
}
}
这是条件,它检查嵌套数组Id是否与父级的fed对象的id匹配:
const AttachedComment = props => {
if(props.commentObj.blogIdHash == props.blogComponentId){
return (
<Comment {...props.commentObj} key={props.commentObj.blogCommentId}/>
)
} else {
return null;
}
}
最后,如果返回TRUE
,则会显示出现错误的组件:
const Comment = props => {
return (
<div className="comment-comment__record">
<div className="row">
<div className="col-md-12">
<div className="comment-comment__meta">
<div className="row">
<div className="col-md-6">
<img src={props.user.picture} className="comment-comment__record-profile"/>
</div>
<div className="col-md-6">
</div>
</div>
</div>
<h5>{props.user_id}</h5>
<h4>{props.comment}</h4>
<h3>{props.synotate_user.fullNameSlug}</h3>
</div>
</div>
</div>
)
}