2017-05-27 78 views
0

我正在开发一个项目,其中有一个页面,您可以在其中上传一些图像。在这个页面上应该可以上传几张图片,所以为此我创建了一个组件,目的是重用它。然而,它似乎与所有相同类型的组件共享状态。重用组件,但没有共享相同状态的所有重用组件

我创建了一个名为Upload的组件。该上传组件在该状态下具有文件和imagePreviewUrl。当我在我的应用程序中渲染组件的多个实例时,它将共享此状态。这意味着无论点击哪个上传按钮,它都会在第一个框中显示图像预览。同样,如果我再次点击任何上传按钮,它将覆盖第一个选定的图像。

我对React很新,所以我不知道我应该如何解决这个问题。如果解决方案是每个组件都创建它自己的独立状态(如果可能的话),或者每个组件都共享相同的状态,并且文件/图像预览以这种状态存储在数组/对象中?

Codepen:https://codepen.io/YOLOSTEVE/pen/mmYVMB?editors=0010

class Upload extends React.Component { 
    constructor(props) { 
     super(props); 
     this.state = { 
      file: '', 
      imagePreviewUrl: '' 
     } 
    } 

    handleImageChange(e){ 
     e.preventDefault(); 

     let file = e.target.files[0]; 

     if(file){ 
      let reader = new FileReader(); 

      reader.onloadend =() => { 
       this.setState({ 
        file: file, 
        imagePreviewUrl: reader.result 
       }); 
      }; 

      reader.readAsDataURL(file); 
     } 
    } 

    handleDeleteImage(){ 
     this.setState({ 
      file: '', 
      imagePreviewUrl: '' 
     }); 
    } 

    render() { 
     let {imagePreviewUrl} = this.state; 
     let $imagePreview = null; 
     if(imagePreviewUrl) { 
      $imagePreview = (
       <div className="imgPreview"> 
        <img src={imagePreviewUrl} /> 
        <span id="file-selected"><strong>{this.state.file.name}</strong></span> 
        <p className="cancel-upload" onClick={this.handleDeleteImage.bind(this)}><span><strong>X</strong></span></p> 
       </div> 
      ); 
     } else { 
      $imagePreview = (
       <div className="imgPreview"> 
        <div className="previewText"> 
         <p><strong>Please select an Image for Preview</strong></p> 
        </div> 
       </div> 
      ); 
     } 

     return(
      <div className="previewComponent"> 
       <p><strong>{this.props.title}</strong> ({this.props.specs})</p> 

       <div className="upload-image"> 

        {$imagePreview} 

        <label htmlFor="file-upload" className="custom-upload"><span>Upload</span></label> 

        <input 
         id="file-upload" 
         className="fileInput" 
         type="file" 
         onChange={(e)=>this.handleImageChange(e)} 
        /> 

       </div> 
      </div> 
     ) 
    } 
} 

class App extends React.Component { 
constructor(props) { 
     super(props); 
     this.state = { 
     } 
    } 

    handleSubmit(e){ 
     e.preventDefault(); 

     // Do something 
    } 

    render() { 
     return(
      <div> 
       <form onSubmit={this.handleSubmit.bind(this)}> 

        <Upload 
         title="Title 1" 
         specs="Description of first upload" 
        /> 
        <Upload 
         title="Title 2" 
         specs="Description of the second upload" 
        /> 
        <Upload 
         title="Title 3" 
         specs="Description of the third upload" 
        /> 

        <hr/> 

        <div className="question-action-buttons"> 
         <button className="save-button">Save</button> 
        </div> 

       </form> 

      </div> 
     ) 
    } 
} 

ReactDOM.render(<App />, document.getElementById('root')); 

回答

2

这不是因为部件共享相同的状态。这是因为您对file input元素的id进行了硬编码。当您渲染所有3 Upload组件时,您有3个输入元素具有相同的id

<input 
     id={this.props.id} 
     className="fileInput" 
     type="file" 
     onChange={(e)=>this.handleImageChange(e)} 
        /> 

然后在您的App组件:

<Upload 
    id="input-1" 
    title="Title 1" 
    specs="Description of first upload" 
/> 
<Upload 
    id="input-2" 
    title="Title 2" 
    specs="Description of the second upload" 
/> 
<Upload 
    id="input-3" 
    title="Title 3" 
    specs="Description of the third upload" 
/> 

现在它应该工作所以在Upload组件作为更新代码。这是一个工作pen