ReactJS条件渲染问题:未提交表单即提前渲染URL按钮
Let's break down what's going wrong here and fix it step by step:
The Root Problem
Your current logic uses if (this.state.url === "") to toggle between showing the form and the button. This means the moment you type the first character into the URL input, url is no longer empty, so the component switches to rendering the button immediately—before you've even submitted the form. That's not what you want!
How to Fix It
We need to separate the form input state (for the current, unsaved title/URL) from the saved links state (the buttons you've already submitted). Here's the adjusted approach:
- Keep the form visible at all times (so users can add multiple links if they want)
- Only add a new button to the rendered list after the form is submitted
- Clear the form inputs after submission to make room for the next link
Modified Component Code
import React, { Component } from 'react'; export default class URLButton extends Component { constructor(props) { super(props); this.state = { links: [], // Stores all submitted links currentUrl: '', // Temporary state for the URL input currentTitle: '' // Temporary state for the Title input }; } // Handle input changes for both fields handleInputChange = (e) => { const { name, value } = e.target; this.setState({ [`current${name.charAt(0).toUpperCase() + name.slice(1)}`]: value }); }; // Handle form submission handleSubmit = (e) => { e.preventDefault(); // Only add the link if both fields have values if (this.state.currentUrl && this.state.currentTitle) { this.setState(prevState => ({ links: [...prevState.links, { url: prevState.currentUrl, title: prevState.currentTitle }], // Clear the form inputs after submission currentUrl: '', currentTitle: '' })); } }; render() { return ( <> {/* Render all submitted links */} <div className="submitted-links"> {this.state.links.map((link, index) => ( <a key={index} href={link.url} className="link-button" target="_blank" rel="noopener noreferrer" > {link.title} </a> ))} </div> {/* The form stays visible for adding new links */} <form onSubmit={this.handleSubmit}> <input name="title" type="text" placeholder="add button text" value={this.state.currentTitle} onChange={this.handleInputChange} /> <input name="url" type="url" placeholder="your-link.com" value={this.state.currentUrl} onChange={this.handleInputChange} /> <br /> <button type="submit">Submit</button> </form> </> ); } }
Key Changes Explained
- Separated State: We split the state into
links(saved buttons) andcurrentUrl/currentTitle(temporary form inputs) to avoid mixing unsaved and saved data. - Fixed Form Structure: The Submit button is now inside the
<form>element, so clicking it properly triggers thehandleSubmitfunction (your original code had the button outside the form, which meantonSubmitnever ran!). - Controlled Inputs: We added
valueprops to the inputs to make them controlled components, ensuring the state and input values stay in sync. - Conditional Submission: We check that both fields have values before adding a new link to the list, preventing empty buttons.
- Persistent Form: The form remains visible after submission, so users can add as many links as they need.
Quick Notes
If you only want to show one button at a time (replacing the form after submission), you could adjust the logic to use a single saved link instead of an array—but the array approach is more flexible for multiple links. Also, using index as the key works for simple cases, but if you plan to edit/delete links later, you should use a unique identifier for each link instead.
内容的提问来源于stack exchange,提问作者Noble Polygon

