ReactJS实现关联双输入框动态表单及代码逻辑疑问求助
Hey there! Let's break this down step by step for you.
First, let's clarify the add() function question
In your single-input code, when you do [...previousState.stuff, ''], you're adding an empty string as a new entry in the stuff array. Here's why that works:
- Your
rendermethod maps over thestuffarray to create input fields. Each element in the array corresponds to the value of one input. - Adding an empty string gives the new input a starting value of empty (so it doesn't show
undefined), and tells React to render one more input field since the array length increased by 1.
Now, let's solve the double-input dynamic form
The key issue with your current state structure (stuff: { item: [], quantity: [] }) is that it keeps item and quantity in separate arrays—this makes it hard to link each pair of inputs together. Instead, we should use an array of objects, where each object holds both the item and quantity for a single input pair. That way, each pair is tied together as a single unit.
Here's the full solution:
1. Initialize the state correctly
state = { stuff: [] // Each element will be { item: '', quantity: '' } };
2. Update the add() function
Now we add a new object with empty values for both inputs:
add() { this.setState(previousState => ({ stuff: [...previousState.stuff, { item: '', quantity: '' }] })); }
3. Update the handleChange function
We need to know which input pair (index) we're updating, and which field (item/quantity) changed. We'll pass both pieces of info to the handler:
handleChange(index, field, event) { // Make a copy of the current state array const updatedStuff = [...this.state.stuff]; // Update the specific field of the specific object updatedStuff[index][field] = event.target.value; // Set the new state this.setState({ stuff: updatedStuff }); }
4. Update the removeInput function
This stays mostly the same—we just remove the entire object at the given index:
removeInput(index) { const updatedStuff = [...this.state.stuff]; updatedStuff.splice(index, 1); this.setState({ stuff: updatedStuff }); }
5. Update the render method
Now we render each pair of inputs, linking them to their respective fields in the state objects:
render() { return ( <div> {/* Render all input pairs */} {this.state.stuff.map((pair, index) => ( <div key={index}> <input type="text" placeholder="Item" value={pair.item} onChange={this.handleChange.bind(this, index, 'item')} /> <input type="text" placeholder="Quantity" value={pair.quantity} onChange={this.handleChange.bind(this, index, 'quantity')} /> <button onClick={this.removeInput.bind(this, index)}>Remove</button> </div> ))} {/* Add button to create new pairs */} <button onClick={this.add.bind(this)}>Add Pair</button> </div> ); }
Why this works
- Each input pair is represented as a single object in the
stuffarray, soitemandquantityare naturally linked to each other. - The
handleChangefunction targets exactly which field of which pair to update, so changes stay synced to the correct inputs. - Adding a new pair just adds a new object to the array, which the
mapfunction picks up to render a new set of inputs.
内容的提问来源于stack exchange,提问作者ilia

