TypeError:在reactjs中设置状态时未定义

时间:2018-02-21 09:12:55

标签: reactjs firebase firebase-realtime-database firebase-storage

我正在尝试将文件从reatjs上传到firebase存储。我还想在实时数据库中保存网址。我已经上传了文件,现在我想获取文件名以保存在数据库中。但是使用setState方法在变量中保存文件名时,它告诉我这是未定义的

     handleSubmitFirebase(event) {

        alert(this.state.avatarURL);
        var docInfo = {
            title: this.docnm.value,
            path: this.state.avatarURL,
            document_type: this.doc_type.value,
            unm: this.unm.value,
            D_id: DbConfig.database()
                .ref("documents")
                .push(docInfo).key
        }; //documents info

        DbConfig.database()
            .ref("documents")
            .push(docInfo);
        this.docnm.value = ""; // <- clear the input
        alert("Successfully Added");
    }
     handlePdfUploadSuccess(filename) {

        alert(filename);

        this.setState({ avatar: filename, progress: 100, isUploading: false }); //error line
        DbConfig.storage().ref('upload/').child(filename).getDownloadURL().then(url => this.setState({ avatarURL: url }));
    }

 <form onSubmit={this.handleSubmitFirebase}>
                                    <div className="form-group label-floating is-empty">
                                        <label className="control-label">Document Name</label>
                                        <input type="text" className="form-control" ref={el => (this.docnm = el)} onChange={this.handleChange} />
                                        <span className="material-input"></span></div>
                                    <div className="form-group label-floating is-empty">
                                        <label className="control-label">Document type</label>
                                        <div className="room-main">
                                            <div className="online-est">
                                                <select className="room-form" ref={el => (this.doc_type = el)}>
                                                    <option value="Circular">Circular</option>
                                                    <option value="User">User</option>
                                                </select>
                                            </div>
                                        </div>
                                        <span className="material-input"></span></div>
                                    <div className="form-group label-floating is-empty">
                                        <label className="control-label">User Name</label>
                                        <div className="room-main">
                                            <div className="online-est">
                                                <select className="room-form">
                                                    {this.renderUserInput()}
                                                </select>
                                            </div>
                                        </div>
                                        <span className="material-input"></span></div>

                                    <div className="form-group  label-floating is-empty">
                                        <label className="control-label">Document</label>
                                        <FileUploader
                                            accept="pdf,doc/*"
                                            name="avatar"
                                            randomizeFilename
                                            storageRef={DbConfig.storage().ref('upload/')}
                                            onUploadStart={this.handlePdfUploadStart}
                                            onUploadError={this.handlePdfUploadError}
                                            onUploadSuccess={this.handlePdfUploadSuccess}
                                        />
                                        <img src={this.state.avatarURL}/>                                    
                                        <span className="material-input"></span></div>
                                    <button type="submit" className="btn btn-fill btn-rose submit_btn">Submit</button>
                                </form>

2 个答案:

答案 0 :(得分:1)

原因是handlePdfUploadSuccess作为事件处理程序,具有自己的this上下文。您可以通过将this转换为箭头函数来获取组件的handlePdfUploadSuccess上下文,如下所示:

handlePdfUploadSuccess = filename => {

    alert(filename);

    this.setState({ avatar: filename, progress: 100, isUploading: false }); //error line
    DbConfig.storage().ref('upload/').child(filename).getDownloadURL().then(url => this.setState({ avatarURL: url }));
}

<强>更新

添加了修改后的handleSubmitFirebase函数,作为在数据库中保存新条目的示例:

handleSubmitFirebase(event) {
    alert(this.state.avatarURL);
    var newEntry = DbConfig.database().ref("documents").push()
    var docInfo = {
        title: this.docnm.value,
        path: this.state.avatarURL,
        document_type: this.doc_type.value,
        unm: this.unm.value,
        D_id: newEntry.key
    }; //documents info
    newEntry.set(docInfo);
    this.docnm.value = ""; // <- clear the input
    alert("Successfully Added");
}

答案 1 :(得分:1)

您有几种方法可以解决此错误。问题是上下文。 你要么(在构造函数中):

this.handlePdfUploadSuccess = this.handlePdfUploadSuccess.bind(this)

或者您将方法更改为箭头函数(将其绑定到自身):

handlePdfUploadSuccess = filename => { // logic here }

或者,在jsx部分(内部渲染)中:

onUploadSuccess={this.handlePdfUploadSuccess.bind(this)}

在性能和捆绑大小方面,第一种方法是最好的。但它的代码可读性条款第二是首选。另外,避免第三种方式:)。另外,从那里删除//filename={file => this.docnm + file.name.split('.')[1] },有时解析器不喜欢jsx组件中的那些注释。