2017-05-27 230 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