代码之家  ›  专栏  ›  技术社区  ›  Mahi Parmar

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

  •  2
  • Mahi Parmar  · 技术社区  · 7 年前

    我正在尝试将文件从reatjs上载到firebase存储。我还想在实时数据库中保存url。我已经上传了文件,现在我想把文件名保存在数据库中。但当使用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 回复  |  直到 7 年前
        1
  •  1
  •   Miguel Calderón    7 年前

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

    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");
    }
    
        2
  •  1
  •   João Vilaça    7 年前

    有几种方法可以修复此错误。问题在于背景。 您可以(在构造函数中)执行以下操作:

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

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

    handlePdfUploadSuccess = filename => { // logic here }
    

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

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

    就性能和捆绑包大小而言,第一种方法是最好的。但就代码可读性而言,第二个是首选。另外,避免第三种方法:)。同时,拆下 //filename={file => this.docnm + file.name.split('.')[1] } 因此,有时解析器不喜欢jsx组件中的那些注释。