我们怎样才能将FileReader的结果传递给React中的父状态?

时间:2018-02-08 10:37:40

标签: reactjs url

您好,谢谢您的时间。

我正在学习React。

我正在尝试重构一个组件来分离并将状态放入一个名为App的顶级组件中,然后创建ImageUpload,它呈现文件输入和画布,一个无状态组件。

代码:

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import registerServiceWorker from './registerServiceWorker';

class ImageUpload extends React.Component {


    _handleImageChange(e) {
        console.log("Enter");
        e.preventDefault();

        let reader = new FileReader();
        let newFile = e.target.files[0];
        console.log("File event: " + newFile);
        this.props.onChange(newFile, reader);
        console.log("File event after: " + newFile);

        reader.readAsDataURL(newFile)
    }

    render() {
        let imagePreviewUrl = this.props.upload;
        console.log("URL IS: " + imagePreviewUrl);
        let $imagePreview = null;
        if (imagePreviewUrl) {
            $imagePreview = (<img src={imagePreviewUrl}/>);
        } else {
            $imagePreview = (
                <div className="previewText">Por favor seleccione una imagen de su ordenador para visualizarla</div>);
        }

        return (
            <div className="previewComponent">
                <form>
                    <input className="fileInput"
                           type="file"
                           onChange={(e) => this._handleImageChange(e)}/>
                </form>
                <div className="imgPreview">
                    {$imagePreview}
                </div>
            </div>
        )
    }
}

class App extends React.Component {
    state = {file: '', upload: ''};

    setFileFromUrl = (newFile, reader) => {
        console.log("The image file in APP method is: " + newFile);
        console.log("reader is:  " + reader);
        this.setState({
            file: newFile,
            upload: reader.result
        })
        ;
        console.log("Changed image file " + (this.state.file));
        console.log("Changed READER TO " + this.state.upload);
    };

    render() {
        return (
            <div>
                <ImageUpload onChange={this.setFileFromUrl} file={this.state.file} upload={this.state.upload}/>
            </div>
        )
    }
}

ReactDOM.render(<App/>, document.getElementById("mainApp"));
registerServiceWorker();

HTML:

<h3>Suba una imagen desde el ordenador, para mostrarla:</h3>
<div id="mainApp"></div>

代码基于:https://codepen.io/hartzis/pen/VvNGZP

我研究过官方教程和本课程:https://app.pluralsight.com/library/courses/react-js-getting-started/table-of-contents

我面临的困难是我希望能够从ImageUpload子组件更新App的状态。目前,我可以更新App的状态文件。但是,我不知道如何对App的状态上传条件做同样的事情,该条件告诉画布是否显示要求输入和图像的字符串或显示它。

输出: 首先,当我们加载页面时,状态为:

State
file:
""
upload:
""

然后当我们上传图片时:

State
file:
File{…}
upload:
null

为什么上传空?

同样记录结果是:

index.js:10 Enter
index.js:15 File event: [object File]
index.js:52 The image file in APP method is: [object File]
index.js:53 reader is:  [object FileReader]
index.js:59 Changed image file 
index.js:60 Changed READER TO 
index.js:17 File event after: [object File]
index.js:24 URL IS: null

因此,当ImageUpload中存在onChange时,我们会看到File通过setFileFromUrl方法从ImageUpload流向App状态。

为什么网址为空?

我们知道FileReader存在于setFileFromUrl中,我们认为我们更新了App的状态上传:

upload: reader.result

此外,使用开发工具,我尝试手动将其更改为true:

画布中的输出是它试图显示某些内容,但它只显示默认缩略图: enter image description here

能帮帮我吗,谢谢!!!

1 个答案:

答案 0 :(得分:0)

您忘记使用reader.onloadend,将其添加到onChange来电:

_handleImageChange(e) {
    console.log("Enter");
    e.preventDefault();
    let reader = new FileReader();
    let newFile = e.target.files[0];
    reader.onloadend = () => {
        this.props.onChange(newFile, reader);
    }
    reader.readAsDataURL(newFile)
}

工作代码:https://codepen.io/Dyo/pen/LQxEYQ?editors=0110

此外,请勿在{{1​​}}之后立即记录this.state,因为setState是异步的,因此不会记录更新的值。