重新使用没有所有重用组件的组件共享相同的状态

时间:2017-05-27 20:36:19

标签: reactjs

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

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

我对React很新,所以我不确定我应该如何解决这个问题。解决方案应该是每个组件创建自己的独立状态(如果可能的话),或者每个组件是否共享相同的状态,文件/ imagepreviews是否存储在此状态的数组/对象中?

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'));

1 个答案:

答案 0 :(得分:2)

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

<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"
/>

现在它应该工作了。这是一个有效的pen