reactjs - 如何防止地图循环中重复的onChange值
问题描述
我试图防止 onChange 值在每个项目中重复。
例如
评论的 onChange 方法
handleCommentChange = (e) => {
this.setState({
comment_body: e.target.value
})
}
我假设我必须遍历 onChange 方法中的键或其他内容。我不确定我会怎么做。
就像是
伪尝试
Object.keys(this.state.items).forEach(key){
this.setState({
comment_body: e.target.value[key]
})
}
或者,还有更好的方法 ?没有把握。
地图迭代代码
{this.state.images.length > 0 ? (
this.state.images.map( (img, i) => (
<Grid item sm={12} md={12} key={img.id} style={{ margin: '30px 0px'}}>
<Paper style={{padding:'20px 20px'}}>
{/* // empty image_title */}
<Typography style={{ padding: '30px 5px', letterSpacing:'8px', textTransform:'uppercase'}} variant="h4" align="center">{img.image_title}</Typography>
<Divider style={{ width: '150px', margin:'10px auto', backgroundColor:'#000000'}} variant="middle" />
<Image image_url={img.img_url} />
<Typography variant="h6" align="center">{img.user.username}</Typography>
<Typography variant="h6" align="center">{moment(img.created_at).calendar()}</Typography>
<Button onClick ={() => this.writeComment(img.id)} variant="outlined" component="span" color="primary">
{this.state.isComment === img.id ? "Close" : "Write A Comment"}
</Button>
{/* here were prevent comments being selected for all items in the array, renders the comment form you clicked on. */}
{this.state.isComment === img.id ?
<Comment onSubmit={this.commentSubmit}
commentBody={this.state.comment_body }
commentChange={this.handleCommentChange}/>
: null}
{/* hide delete button when user enters comment */}
{!this.state.isComment ? <Button style={{margin: '0px 20px'}} onClick={() => this.deleteImg(img.id)} variant="outlined" component="span" color="primary">
Delete
</Button> : null}
</Paper>
</Grid>
))
) : (
<div>
<Grid item md={8}>
<Typography>No Images yet</Typography>
</Grid>
</div>
)}
解决方案
问题是您的所有评论都引用了组件状态中的相同值。我想在你之前的问题中谈到这一点。
你应该做的是将你的 Grid 标记分成它自己的组件,如下所示:
ImageContainer.js
import React, { Component } from "react";
import Button from '@material-ui/core/Button';
import TextField from '@material-ui/core/TextField';
import Grid from '@material-ui/core/Grid';
import Typography from '@material-ui/core/Typography';
import Paper from '@material-ui/core/Paper';
import Divider from '@material-ui/core/Divider';
import Image from './Image';
import moment from 'moment';
import Comment from './Comment';
class ImageContainer extends React.Component{
state = {
isComment: false,
comment_body: ""
}
handleCommentChange = (e) => {
this.setState({
comment_body: e.target.value
})
}
writeComment = (id) => {
this.setState({
isComment: this.state.isComment ? '' : id // check if you state is filled to toggle on/off comment
})
}
commentSubmit = (e) => {
e.preventDefault();
console.log(this.state.comment_body);
// Axios.post('/images/newComment', this.state.comment_body).then( (response )=> {
// const newComment = { ...response.data};
// console.log(newComment);
// this.setState({
// comment_body: ''
// })
// })
}
render(){
const { img } = this.props
return(
<Grid item sm={12} md={12} key={img.id} style={{ margin: '30px 0px'}}>
<Paper style={{padding:'20px 20px'}}>
{/* // empty image_title */}
<Typography style={{ padding: '30px 5px', letterSpacing:'8px', textTransform:'uppercase'}} variant="h4" align="center">{img.image_title}</Typography>
<Divider style={{ width: '150px', margin:'10px auto', backgroundColor:'#000000'}} variant="middle" />
<Image image_url={img.img_url} />
<Typography variant="h6" align="center">{img.user.username}</Typography>
<Typography variant="h6" align="center">{moment(img.created_at).calendar()}</Typography>
<Button onClick ={() => this.writeComment(img.id)} variant="outlined" component="span" color="primary">
{this.state.isComment === img.id ? "Close" : "Write A Comment"}
</Button>
{/* here were prevent comments being selected for all items in the array, renders the comment form you clicked on. */}
{this.state.isComment === img.id ?
<Comment onSubmit={this.commentSubmit}
commentBody={this.state.comment_body }
commentChange={this.handleCommentChange}/>
: null}
{/* hide delete button when user enters comment */}
{!this.state.isComment ? <Button style={{margin: '0px 20px'}} onClick={() => this.deleteImg(img.id)} variant="outlined" component="span" color="primary">
Delete
</Button> : null}
</Paper>
</Grid>
)
}
}
export default ImageContainer
现在每个 ImageContainer 都有自己的状态值来跟踪和更新。所以没有重复。
然后在您的Dashboard
组件中,只需导入ImageContainer
.
import ImageContainer from "./ImageContainer"
现在对于我们中的每个图像.map()
,我们将创建一个唯一的实例component
,并将图像作为道具传递给ImageContainer
.
{this.state.images.length > 0 ? (
this.state.images.map( (img, i) => (
<ImageContainer img={img}/>
))
) : (
<div>
<Grid item md={8}>
<Typography>No Images yet</Typography>
</Grid>
</div>
)}
还要记住将您的事件处理程序连接到您的Comment
组件。至少它需要使用props
你传入的。
评论.js
import React from "react";
const Comment = props => {
return (
<form onSubmit={props.onSubmit}>
<input
onChange={props.commentChange}
value={props.commentBody}
/>
</form>
);
};
export default Comment;
这里也是一个沙箱,我没有你的Comment
组件代码,所以它不会有相同的样式:https ://codesandbox.io/s/young-pine-zmpvr