React项目中实现输入框输入时动态显示Submit Edit按钮的问题求助
Let's fix this properly using React's state management instead of jQuery—since React relies on state to drive the UI, direct DOM manipulation (like jQuery does) will cause inconsistencies and break React's rendering flow. Here's how to implement the "only show Submit Edit when inputs change" behavior:
Step 1: Track Input Changes with Component State
First, we'll add an editStates object to your component's state to track the current input values for each row. This lets us compare the edited values against the original data to determine if changes were made.
Step 2: Update Inputs to Use State and Handle Changes
Replace the static placeholders with state-driven values, and add onChange handlers to update the state whenever the user types in an input. We'll also fix the duplicate id issue (since multiple rows can't share the same id).
Step 3: Conditionally Render the Submit Button
Only show the "Submit Edit" button when the current input values differ from the original data for that row.
Full Modified Code
import React, { Component } from "react"; import axios from "axios"; import "../styles/TourPage.css"; class TourPage extends Component { constructor(props) { super(props); this.state = { myData: [], isLoading: true, editStates: {} // Tracks input values for each row, keyed by document _id }; } componentDidMount() { axios .get("/getResults") .then((res) => { this.setState({ myData: res.data }); }) .catch((error) => { console.log(error); }) .finally(() => { this.setState({ isLoading: false }); }); } deleteById = (id) => { axios .post(`/deleteDoc`, { id: id }) .then(() => { console.log(id, " worked"); window.location = "/tour"; }) .catch((error) => { console.log(error); }); }; // Handle input changes for a specific row and field handleInputChange = (rowId, fieldName, value) => { this.setState((prevState) => ({ editStates: { ...prevState.editStates, [rowId]: { ...prevState.editStates[rowId], [fieldName]: value } } })); }; editById = (rowId) => { // Get original data for the row const originalRow = this.state.myData.find((item) => item._id === rowId); // Use edited values if available, fall back to original const editedValues = this.state.editStates[rowId] || {}; const submitData = { id: rowId, location: editedValues.location || originalRow.location, Services: editedValues.Services || originalRow.Services, cnum: editedValues.cnum || originalRow.cnum }; axios .post(`/editDoc`, JSON.stringify(submitData), { headers: { "Content-Type": "application/json" } }) .then(() => { console.log(rowId, " worked"); window.location = "/tour"; }) .catch((error) => { console.log(error); }); }; render() { const { myData, isLoading, editStates } = this.state; return ( <table id="customers"> <tr> <th>siteLocation</th> <th>Services</th> <th>cnum</th> <th>Actions</th> </tr> {myData.length > 0 ? ( myData.map(({ location, Services, cnum, _id }, index) => { // Get current input values (use edited state if exists, else original) const currentLocation = editStates[_id]?.location || location; const currentServices = editStates[_id]?.Services || Services; const currentCnum = editStates[_id]?.cnum || cnum; // Check if any input has changed from original const hasChanges = currentLocation !== location || currentServices !== Services || currentCnum !== cnum; return ( <tr key={index}> <td> <input type="text" value={currentLocation} name="location" id={`location-${_id}`} // Unique ID per row onChange={(e) => this.handleInputChange(_id, "location", e.target.value) } /> </td> <td> <input type="text" value={currentServices} name="Services" id={`Services-${_id}`} onChange={(e) => this.handleInputChange(_id, "Services", e.target.value) } /> </td> <td> <input type="text" value={currentCnum} name="cnumhide" id={`cnumhide-${_id}`} onChange={(e) => this.handleInputChange(_id, "cnum", e.target.value) } /> </td> <td> <button onClick={(e) => { e.preventDefault(); this.deleteById(_id); }} disabled={isLoading} > Delete </button> {/* Only show Submit Edit if changes exist */} {hasChanges && ( <button onClick={(e) => { e.preventDefault(); this.editById(_id); }} > Submit Edit </button> )} </td> </tr> ); }) ) : ( "No Data Found" )} </table> ); } } export default TourPage;
Key Improvements:
- No jQuery Needed: We're using React's state to track changes, which aligns with React's core principles.
- Unique IDs: Each input now has a unique ID (e.g.,
location-${_id}) to avoid conflicts between rows. - Conditional Button Rendering: The "Submit Edit" button only appears when the user has modified any input in the row.
- State-Driven Inputs: Input values are tied to component state, so the UI always reflects the latest user input.
内容的提问来源于stack exchange,提问作者developerg1000

