React实现表单提交后后端返回消息自动消失的方案咨询
Hey there! I see the issue with your current code—right now, the setTimeout in componentDidMount only runs once when the component first loads, not after each form submission. That's why your success message stays visible forever after the first submit. Let's fix this step by step.
The Problem with Your Current Code
Your componentDidMount sets a timer to clear the message 3 seconds after the component mounts, but when you submit the form later and update message via setState, there's no new timer triggered to clear that updated message.
The Solution
We need to trigger a new timer every time we set the success message (right after the axios call succeeds), and also add safeguards to handle multiple rapid submissions and prevent memory leaks.
Here's the revised code with explanations:
import React, { Component } from 'react'; import axios from 'axios'; class Subscribe extends Component { state = { message: '', timerId: null // Store the timer ID to manage it later }; newSubscriber = (newSubscriber) => { axios.post('/subscribe', newSubscriber) .then(res => { // First, clear any existing timer to avoid conflicting with new messages if (this.state.timerId) { clearTimeout(this.state.timerId); } // Set the success message this.setState({ message: res.data.message }, () => { // After state updates, set a new timer to clear the message const newTimerId = setTimeout(() => { this.setState({ message: '', timerId: null }); }, 3000); // Save the new timer ID to state this.setState({ timerId: newTimerId }); }); }) .catch(err => console.log(err)); }; onSubmit = e => { e.preventDefault(); const newSubscriber = { email: this.refs.email.value }; this.newSubscriber(newSubscriber); }; // Clear the timer when the component unmounts to prevent memory leaks componentWillUnmount() { if (this.state.timerId) { clearTimeout(this.state.timerId); } } render() { return ( <form style={{ marginTop: '20px' }} onSubmit={this.onSubmit}> {this.state.message && ( <div style={{ background: "green", color: "white", textAlign: "center", padding: '8px' }}> {this.state.message} </div> )} <div className="form-group"> <label htmlFor="email">Subscribe to get updates</label> <input type="email" ref="email" className="form-control" placeholder="Email address..." /> </div> <button type="submit" className="btn btn-primary">Send</button> </form> ); } } export default Subscribe;
Key Changes Explained:
- Added
timerIdto state: This lets us track the active timer so we can clear it if the user submits again before the message disappears. - Clear existing timer before setting a new one: If the user submits multiple times quickly, we don't want an old timer wiping out a new message prematurely.
- Set timer after state updates: We use the callback in
setStateto ensure the timer is only created after the message is actually rendered. - Clean up timer on unmount: This prevents a warning from React if the component is removed before the timer finishes running.
- Conditional rendering for the message: The message div only renders when
this.state.messageis not empty, so it doesn't take up space when there's no message to show.
This way, every time a user submits the form and gets a success message, it will automatically disappear after 3 seconds—no matter how many times they submit!
内容的提问来源于stack exchange,提问作者Symon Kibaru

