React图片上传组件触发setState的TypeError错误求助
Hey there! Let's break down why you're seeing that error and fix it step by step.
The Root Cause
The error pops up because inside your .then() callback, you're using a regular function() {} which creates its own this context—not pointing to your React component instance. That's why this.setState comes up as undefined here.
Quick Fixes & Improvements
1. Use Arrow Functions for Callbacks
Arrow functions inherit the outer this context (your component), so swapping the regular function with an arrow function will fix the this binding issue instantly:
.then((response) => { // Replace function(response) with arrow function console.log('then: ', response); // Note: The line `this.setState({ file: event.target.files[0] });` was incorrect here— // The submit event doesn't have a file target, and your file is already stored in state from `_handleImageChange`! }) .catch((response) => { // Do the same for the catch callback console.log('catch: ', response); });
2. Fix Your Axios Request Configuration
Your current axios setup is passing a postData object as request data, which is wrong. You need to send the FormData directly, and set credentials properly:
_handleSubmit(e) { e.preventDefault(); let fd = new FormData(); fd.append('image', this.state.file); axios({ method: 'post', url: `/api/gaming/profiles/${this.props.profileId}/files/upload`, data: fd, // Send the FormData directly headers: { 'content-type': 'multipart/form-data' }, withCredentials: true // Equivalent to credentials: 'include' }) .then((response) => { console.log('then: ', response); // Optional: Clear the file state after successful upload // this.setState({ file: '', imagePreviewUrl: '' }); }) .catch((response) => { console.log('catch: ', response); }); }
3. Optional: Bind Methods in the Constructor (For Better Performance)
While using arrow functions in render works, binding your methods in the constructor avoids creating a new function on every render:
constructor(props) { super(props); this.state = { file: '', imagePreviewUrl: '' }; // Bind the component methods this._handleSubmit = this._handleSubmit.bind(this); this._handleImageChange = this._handleImageChange.bind(this); }
Then simplify your render event handlers:
<input className="fileInput" type="file" onChange={this._handleImageChange} /> <button className="submitButton" type="submit" onClick={this._handleSubmit}>Upload Image</button>
Full Corrected Component Code
import React, { Component } from 'react'; import axios from 'axios'; class ImageUpload extends Component { constructor(props) { super(props); this.state = { file: '', imagePreviewUrl: '' }; this._handleSubmit = this._handleSubmit.bind(this); this._handleImageChange = this._handleImageChange.bind(this); } _handleSubmit(e) { e.preventDefault(); let fd = new FormData(); fd.append('image', this.state.file); axios({ method: 'post', url: `/api/gaming/profiles/${this.props.profileId}/files/upload`, data: fd, headers: { 'content-type': 'multipart/form-data' }, withCredentials: true }) .then((response) => { console.log('then: ', response); // Optional: Clear state after successful upload // this.setState({ file: '', imagePreviewUrl: '' }); }) .catch((response) => { console.log('catch: ', response); }); } _handleImageChange(e) { e.preventDefault(); let reader = new FileReader(); let file = e.target.files[0]; reader.onloadend = () => { this.setState({ file: file, imagePreviewUrl: reader.result }); } reader.readAsDataURL(file) } render() { const { questionId } = this.props; let { imagePreviewUrl } = this.state; let $imagePreview = null; if (imagePreviewUrl) { $imagePreview = (<img src={imagePreviewUrl} />); } else { $imagePreview = (<div className="previewText">Please select an Image for Preview</div>); } console.log('ImageUpload Render()'); return ( <div className="previewComponent"> <input className="fileInput" type="file" onChange={this._handleImageChange} /> <button className="submitButton" type="submit" onClick={this._handleSubmit}>Upload Image</button> <div className="imgPreview"> {$imagePreview} </div> </div> ); } } export default ImageUpload;
That should resolve the setState undefined error and get your upload functionality working correctly!
内容的提问来源于stack exchange,提问作者SkyeBoniwell

