I am mapping items in react, each item has a text area underneath for a comment, when I type in one box the text appears in all the boxes. I know it's because the values are the same this.state.comment but I not sure how to fix it. I have tried changing the value but i haven't figured out a way that would work since the the number of item can be 1 or 1000 depending on how many items are added.
class Content extends React.Component {
state = {
allUserItems: [],
image: null,
url: "",
video: "",
isActive: false,
isActive2: false,
comment: "",
checkInputID: null,
whichComment: null,
optionId: "",
edit_id: "",
editContent: "",
editPicture: "",
comment_id: "",
comOption_id: "",
postComment_id: "",
editComment: "",
isNotiOpen:false,
componentDidMount() {
console.log(this.props)
this.listFriendsItems()
}
listFriendsItems = () => {
API.getFriendsItems({ friends: this.props.userInfo.friends, })
.then(res => {
this.setState({ allUserItems: res.data })
console.log(res.data)
})
.catch(err => console.log(err));
}
handleChange = e => {
this.setState({
[e.target.name]: e.target.value
});
};
submitComment = (id,posters_id) => {
API.saveComment(id, {
comment: this.state.comment,
user_id: this.props.userInfo.user_ID,
user: this.props.userInfo.firstname + " " +
this.props.userInfo.lastname,
picUrl: this.state.url,
})
.then(res => console.log(res))
.catch(err => console.log(err));
let data ={
comment: this.state.comment,
user_id: this.props.userInfo.user_ID,
name: this.props.userInfo.firstname + " " +
this.props.userInfo.lastname,
userPic: this.state.url,
}
if(this.props.userInfo.user_ID !== posters_id){
this.props.saveNotification(posters_id,data,id)
}
this.setState({ comment: "", checkInputID: null }, () =>
this.listFriendItems());
}
<section className="feed ">
{this.state.allUserItems.length ? (
<div>
{this.state.allUserItems.map(content => {
return (
<div className="feed_Container" key={content._id} >
<div className="info">
<div className="uploadedInfo">
{(content.picUrl === "" ) ? <div
className="story"> </div> :
<div className="miniUpImage"><img
className={`${(content.picUrl === "") ? "story" : "miniUpImage"}`} src=
{content.picUrl} alt="uploaded pic" /></div>
}
<div className={(content.videoUrl ===
"") ? "noVideo" : "uploadedVideo"}> <VideoPost video={content.videoUrl} />
</div>
</div>
<div className="colorBackground">
<div className="updateInfo">
<div className="timenOptions">
<div className="time">{moment(content.dateCreated).calendar()}</div>
<div className=
{(this.state.optionId === content._id) ? "optionsContainer active" :
"optionsContainer"} onClick={() => this.optionsClicked(content._id)} >
<div className=
{(content.user_ID === this.props.userInfo.user_ID) ? "options" :
"noOptions"}> ...</div>
<div
className="optionsDropdown">
<ul
className="optionsList">
<div
className="edit" onClick={() => this.editPostClicked(content._id,
content.content, content.picUrl)}> Edit</div>
<div
className="delete" onClick={() => this.removePost(content._id)}>Delete</div>
</ul>
</div>
</div>
</div>
<p>{content.content}
</p>
</div>
</div>
<div className="mapComments">{content.comments.map((comment, picUrl) =>
<div key={picUrl} className="commentList"><div className="timeStamp">
{moment(comment.dateCreated).calendar()}<div>
<div className={(this.state.comOption_id ===
comment._id"comOptionsContainer active" : "comOptionsContainer"}
onClick={() => this.commentOptions(comment._id)} >
<button type="button" className={(comment.user_id ===
this.props.userInfo.user_ID) ? "commentOptions" : "noOptions"} ><i
class="far fa-comment-dots"></i></button>
<div className="comOptionsDropdown">
<ul className="optionsList">
<div className="edit" onClick={() =>
this.editCommentClicked(content._id,
comment._id, content.content, comment.comment, content.picUrl)}>
Edit</div>
<div className="delete" onClick={() => this.removeComment(content._id,
comment._id)}>Delete</div>
</ul>
</div>
</div>
</div> </div><span> <strong>{comment.user} </strong>
</span>
{comment.comment}
<div className=
{(comment.picUrl !== "") ? "commentPic" : "nocommentPic"}><img
className="commentUrl" src={comment.picUrl} alt="comment pic" /></div>
</div>
)}
<div className="responseComments">
<textarea name="comment" value={this.state.comment} onChange=
{this.handleChange} className="commentArea" placeholder="Comment"
rows="8"
cols="80" />
<div className="commentPhoto">
<button type="button" className="button photo" onClick={() => {
this.fileInput2.click(); this.getID(content._id); }}> <i className="far
fa-images"></i></button>
</div>
</div>
<div>
<input type="file" style={{ display: "none" }} onChange=
{this.handleImageSelected2} ref={fileInput => this.fileInput2 = fileInput}
/>
<img className=
{(this.state.checkInputID === content._id) ? "uploadReady active" :
"uploadReady"} src={this.state.url} alt="preview" height="40" width="50" />
<progress className= {(this.state.checkInputID === content._id) ?
"uploadReady
active" : "uploadReady"} value={this.state.progress} max="100" />
<button className= {(this.state.checkInputID === content._id) ?
"uploadReady
active" : "uploadReady"} onClick={this.handleUpload}>Upload</button>
<span
className={(this.state.checkInputID === content._id) ? "uploadReady active"
:
"uploadReady"}>File </span>
</div>
<div className="commentButtons">
<div className="replyButton" onClick={this.state.comment === "" &&
this.state.url === "" ? null : () =>
this.submitComment(content._id,content.user_ID)} ><i className="fas fa-
share">
<div className="likessection">
{(content.likes.findIndex(i => i.user_id === this.props.userInfo.user_ID) >
-1) ?
<div className="likeButton" onClick={() =>
this.removeLikes(content._id)}>Unlike</div>
: <div className="likeButton" onClick={() =>
this.handleLikes(content._id)}>
<i
className="far fa-thumbs-up"></i></div>}
</div>
</div>
</div>
</div>
</div>
);
})
}
</div>
You have to initialize state comments with the number of comments you have. In your constructor create your comments like this, an array of comments:
this.state= {
comments: new Array(n) //n is your number of comments
}
In the handleChange function, you will have to pass the index of comment to be updated.
handleChange = (commentIndex, e) => {
const commentsUpdated = this.state.comments.map((comment, i) => {
if (i == commentIndex) return e.target.value;
else return comment;
});
this.setState({ comments: commentsUpdated });
};
And you have to update the JSX, you will need to render a collection of comments, and every comment connect with its comment state.
<div className="responseComments">
{this.state.comments.map((comment, i) => (
<textarea
name="comment"
value={comment}
onChange={e => this.handleChange(i, e)}
className="commentArea"
placeholder="Comment"
rows="8"
cols="80"
/>
))}
</div>;
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.