首页 > 解决方案 > 如何防止地图循环中重复的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>
)}

标签: reactjs

解决方案


问题是您的所有评论都引用了组件状态中的相同值。我想在你之前的问题中谈到这一点。

你应该做的是将你的 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


推荐阅读