我认为我在理解状态和道具方面存在一个基本问题……我有一个记录数组,当我console.log该数组时,它返回正确的记录,但是.setState不会更改UI中返回的记录。我想知道是否需要将handleCommentDelete移到父组件?这是父母:
import React from 'react';
import { render } from 'react-dom';
import CommentForm from './CommentForm';
import CommentList from './CommentList';
class CommentBox extends React.Component {
constructor(props) {
super(props);
this.state = { data: [] };
this.handleCommentSubmit = this.handleCommentSubmit.bind(this);
}
componentDidMount() {
this.loadCommentsFromServer();
window.setInterval(
() => this.loadCommentsFromServer(),
this.props.pollInterval,
);
}
handleCommentSubmit(comment) {
const comments = this.state.data;
comment.Id = comments.length + 1;
const newComments = comments.concat([comment]);
this.setState({ data: newComments });
const data = new FormData();
data.append('Id', comment.Id);
data.append('Name', comment.Name);
data.append('Phone', comment.Phone);
data.append('Email', comment.Email);
const xhr = new XMLHttpRequest();
xhr.open('post', this.props.submitUrl, true);
xhr.onload = () => this.loadCommentsFromServer();
xhr.send(data);
}
loadCommentsFromServer() {
const xhr = new XMLHttpRequest();
xhr.open('get', this.props.url, true);
xhr.onload = () => {
const data = JSON.parse(xhr.responseText);
this.setState({ data: data });
};
xhr.send();
}
render() {
return (
<div className="row padBottom_10">
<div className="col-md-12">
<CommentForm onCommentSubmit={this.handleCommentSubmit} />
</div>
<div className="col-md-12">
<div className="commentBox border borderBorderGrey highlightPrimaryGrey">
<CommentList data={this.state.data} />
</div>
</div>
</div>
);
}
}
export default CommentBox;
...这是子组件,我正在尝试删除记录。
import React from 'react';
import { render } from 'react-dom';
class CommentList extends React.Component {
constructor(props) {
super(props);
this.state = {
data: [{}]
};
this.handleCommentDelete = this.handleCommentDelete.bind(this);
}
handleCommentDelete(id) {
console.log(this.props.data); // returns n records
let comments = [...this.props.data];
this.setState({
data: comments.filter(comment => comment.Id !== id)
});
console.log(comments.filter(comment => comment.Id !== id)); // returns n - 1 records
}
render() {
return (
<table className="commentList react-bs-table">
<thead>
<tr>
<th>Name</th>
<th>Phone</th>
<th>Email</th>
<th></th>
</tr>
</thead>
<tbody>
{
this.props.data.map((comment, i) => {
return (
<tr className="comment" key={i}>
<td className="commentId">{comment.Id}</td>
<td className="commentName">{comment.Name}</td>
<td className="commentPhone">{comment.Phone}</td>
<td className="commentEmail">{comment.Email}</td>
<td className="commentCRUD">
<a onClick={() => this.handleCommentDelete(comment.Id)}>
<i className="fa fa-trash" />
</a>
</td>
</tr>
);
})
}
</tbody>
</table>
);
}
}
export default CommentList;
我真的很想在墙上理解这件事……在此先感谢您的帮助!
最佳答案
handleCommentDelete
应该在父组件中。您可以将函数从父级传递给子级作为道具。
将功能传递给子组件<CommentList data={this.state.data} handleCommentDelete={this.handleCommentDelete} />
父功能
handleCommentDelete = (id) => {
this.setState({
data: this.state.data.filter(comment => comment.Id !== id)
});
}
参考道具功能
<a onClick={() => this.props.handleCommentDelete(comment.Id)}>
当孩子应该只是道具时,您正在混合状态和道具。将
handleCommentDelete
作为道具传递给孩子,用this.props.handleCommentDelete(id)
进行调用,并更新父级中的状态以反映删除。然后,它将使用新的评论列表重新呈现子级。