如何实现首个文件上传后新增按钮,且保留原按钮文件名
Alright, let's tackle this problem—you want to show a new file upload button only after the previous one has a file selected, and keep the filenames visible instead of losing them when adding new buttons. Here's how to make that work:
The core issue with your initial approach was that you were only tracking file values in an array, but not associating each file with its original upload entry (so you couldn't render the filename alongside it). Instead, we'll use state to manage an array of file entries, where each entry tracks both the selected file (if any) and whether to show the upload input for that entry.
Step 1: Initialize State for File Entries
In your class component, set up state to hold an array of file entries. We'll start with one entry that's ready to accept a file:
constructor(props) { super(props); this.state = { fileEntries: [ { file: null, showInput: true } // First upload button is visible initially ] }; }
Step 2: Update the Upload Handler to Track Entries
Modify your onImageUpload function to target the specific entry being updated, save the selected file, and add a new entry only when the last upload button has a file:
onImageUpload = (index, e) => { const selectedFile = e.target.files[0]; if (!selectedFile) return; // Create a copy of the entries array to avoid mutating state directly const updatedEntries = [...this.state.fileEntries]; // Update the current entry with the selected file updatedEntries[index] = { ...updatedEntries[index], file: selectedFile }; // If this was the last entry and it now has a file, add a new empty entry if (index === this.state.fileEntries.length - 1) { updatedEntries.push({ file: null, showInput: true }); } this.setState({ fileEntries: updatedEntries }); };
Step 3: Render Entries with Filenames or Upload Buttons
Loop through the fileEntries array in your render method. For each entry:
- If a file is selected, display the filename
- If no file is selected (and
showInputis true), display the upload button
render() { return ( <div className="file-upload-container"> {this.state.fileEntries.map((entry, index) => ( <div key={index} className="file-upload-item"> {entry.file ? ( // Show the filename once a file is selected <span className="selected-filename">{entry.file.name}</span> ) : ( // Show the upload button only if the entry is set to display it entry.showInput && ( <FormControl type="file" accept=".jpg" onChange={(e) => this.onImageUpload(index, e)} /> ) )} </div> ))} </div> ); }
How This Works
- Each upload button is tied to a specific entry in the state array, so we always know which file belongs to which "slot"
- When a file is selected, we replace the upload button with the filename for that entry
- Only after the last entry has a file do we add a new empty entry (with an upload button)
- All previously selected filenames stay visible because they're stored in the state array alongside their respective entries
内容的提问来源于stack exchange,提问作者Tee F

