我有点新的反应,并且有点迷失在这里做什么。我从firebase加载数据并使用.map函数呈现该对象的道具以列出所有评论'在页面上,工作正常。我还想调用一个允许用户回复单个注释的组件(即地图中的一个特定元素),但正如此代码所期望的,当单击回复按钮时,它会在该元素的每个元素下显示被调用的组件。地图,这是不可取的。无论如何,在这种情况下,我可以只为地图的一个元素调用组件吗?
changeIsReply() {
this.setState(
{isReply: !this.state.isReply,}
);
}
render() {
return (
<div>
<ul className="list-group">
{Object.values(this.props.commentInfo).map((data) =>
data.map((secondData, i) =>
<div className="commentHolder" key={i}>
<p>{secondData.text}</p>
<p>{secondData.category}</p>
<p>{secondData.organization}</p>
<button> UpButton </button> <br />
<button> DownButton </button>
<button onClick = {this.changeIsReply} > Reply </button>
{this.state.isReply ? <SetComment id={secondData.key} /> : null}
</div>
)
)}
</ul>
</div>
)
}
答案 0 :(得分:1)
那是因为您对所有评论都使用单一状态。
<button onClick = {() => this.changeIsReply(secondData.key)} > Reply </button>
{this.state.isReply && this.state.clickedComment == {secondData.key} ? <SetComment id={secondData.key} /> : null}
并将changeIsReply()更改为:
changeIsReply(clickedId) {
this.setState(
{isReply: !this.state.isReply, clickedComment: clickedId}
);}
看看这是否有效。别忘了将新状态添加到构造函数中。
答案 1 :(得分:0)
您可以跟踪哪个评论应该包含SetComment组件。
constructor(props) {
super(props);
this.state = {
// init commentReplyIds as empty array
commentReplyIds : [],
// ... rest of your state
}
}
changeIsReply(commentId) {
const newCommentReplyIds = [...this.state.commentReplyIds. commentId];
this.setState(
{commentReplyIds: newCommentReplyIds}
);
}
render() {
// in here I am using the data.text as the unique id of each comment, you can use other serializable value.
return (
<div>
<ul className="list-group">
{Object.values(this.props.commentInfo).map((data) =>
data.map((secondData, i) =>
<div className="commentHolder" key={i}>
<p>{secondData.text}</p>
<p>{secondData.category}</p>
<p>{secondData.organization}</p>
<button> UpButton </button> <br />
<button> DownButton </button>
<button onClick = {() => this.changeIsReply(secondData.text)} > Reply </button>
{this.state.commentReplyIds.includes(secondData.text) ? <SetComment id={secondData.key} /> : null}
</div>
)
)}
</ul>
</div>
)
}
&#13;
使用这种方法,您可以在用户点击回复评论按钮的不同评论中包含多个SetComment
组件。
答案 2 :(得分:0)
您需要将isReply
保留为数组数组,并根据所点击的注释的索引,仅更新正确的值,例如
state= {
isReply: [[]]
}
changeIsReply(i, j) {
var isReply = [...this.state.isReply]
if(isReply[i] === undefined) {
isReply.push([true]) =
} else {
if(isReply[i][j] === undefined) {
isReply[i].push(true)
} else {
isReply[i][j] = !isReply[i][j]
}
}
this.setState(
{isReply}
);
}
render() {
return (
<div>
<ul className="list-group">
{Object.values(this.props.commentInfo).map((data, i) =>
data.map((secondData, j) =>
<div className="commentHolder" key={j}>
<p>{secondData.text}</p>
<p>{secondData.category}</p>
<p>{secondData.organization}</p>
<button> UpButton </button> <br />
<button> DownButton </button>
<button onClick = {() => this.changeIsReply(i, j)} > Reply </button>
{this.state.isReply[i][j] ? <SetComment id={secondData.key} /> : null}
</div>
)
)}
</ul>
</div>
)
}
答案 3 :(得分:0)
我建议将其分为两部分。 CommentList
和Comment
组件。
<强>评论-list.js 强>
import Comment from './comment';
class CommentList extends Component{
render(){
return(
<div>
<ul className="list-group">
{Object.values(this.props.commentInfo).map((data) =>
data.map((secondData, i) =>
<Comment text={secondData.text} category={secondData.category} organization={secondData.organization} key={secondData.key} />
)
</ul>
</div>
)
}
}
<强> comment.js 强>
class Comment extends Component {
constructor(props){
super(props);
this.state = {
isReply: false
}
}
changeIsReply = () => {
this.setState(
{isReply: !this.state.isReply,}
);
}
render(){
const {text, category, organization, key} = this.props;
return(
<div className="commentHolder" key={i}>
<p>{text}</p>
<p>{category}</p>
<p>{organization}</p>
<button> UpButton </button> <br />
<button> DownButton </button>
<button onClick = {this.changeIsReply} > Reply </button>
{this.state.isReply ? <SetComment id={key} /> : null}
</div>
)
}
}
export default Comment;
这样每条评论都可以控制自己的状态以及是否显示SetComment
组件。
尝试制作更多组件,而不是将所有标记放在单个渲染方法中。这也有助于组织代码,以便将每组值映射到组件,我觉得这样可以让您更容易理解。