React Native点击按钮增删输入框及Firebase数据存储实现问询
Hey there! I see you're trying to add dynamic input fields in React Native that you can add/remove with buttons, and save all that data to Firebase. Let's modify your existing code to make this work smoothly. Here's the step-by-step solution:
Step 1: Refactor Your Component State
First, we'll replace your individual measurement fields with an array to hold dynamic input items. Each item will have a unique ID, a label, and its current value:
constructor(props) { super(props); this.state = { // Array to hold all dynamic measurement inputs measurements: [ { id: 'busto', label: 'Contorno busto/cm', value: '' }, { id: 'cintura', label: 'Contorno cintura/cm', value: '' }, { id: 'cadera', label: 'Contorno cadera/cm', value: '' }, ], }; }
Step 2: Add Functions for Adding/Removing Inputs
Create functions to handle adding new inputs and deleting existing ones (we'll keep at least one input to avoid empty state):
// Add a new dynamic input field addInput = () => { const newInput = { id: Date.now().toString(), // Unique ID using timestamp label: `Nuevo contorno/${this.state.measurements.length + 1}/cm`, // Default label (customize as needed) value: '', }; this.setState(prevState => ({ measurements: [...prevState.measurements, newInput], })); }; // Delete an input field by its unique ID deleteInput = (id) => { if (this.state.measurements.length <= 1) { alert('Debe quedar al menos un campo de medida'); return; } this.setState(prevState => ({ measurements: prevState.measurements.filter(item => item.id !== id), })); };
Step 3: Update Input Value Handler
We need a way to update the value of specific input fields when the user types:
updateInputValue = (id, text) => { this.setState(prevState => ({ measurements: prevState.measurements.map(item => item.id === id ? { ...item, value: text } : item ), })); };
Step 4: Modify Validation & Firebase Storage Logic
Update your validation to check all dynamic inputs, then convert the array to a structured object for Firebase storage:
validate = () => { // Check if any input field is empty const hasEmptyFields = this.state.measurements.some(item => item.value.trim() === ''); if (hasEmptyFields) { alert('Hay campos vacíos'); return; } // Convert measurements array to an object for Firebase const measurementsData = this.state.measurements.reduce((acc, item) => { acc[item.id] = item.value; return acc; }, {}); // Save to Firebase firebase.database().ref("medidas/").push(measurementsData) .then(() => { alert("Medidas guardadas"); // Navigate and pass all measurement data this.props.navigation.navigate("DatosCli", { measurements: measurementsData, id: this.props.route.params.id, }); }) .catch(error => { alert(`Error al guardar: ${error.message}`); }); };
Step 5: Render Dynamic Input Fields
Replace your fixed input fields with a map that renders all items in the measurements array. We'll also hook up the add/delete buttons:
render() { return ( <ScrollView> <View style={styles.container}> {/* Render all dynamic input fields */} {this.state.measurements.map(item => ( <View key={item.id} style={styles.inputWrapper}> <Text style={styles.texto}>{item.label}</Text> <View style={styles.input}> <TextInput keyboardType="numeric" value={item.value} onChangeText={(text) => this.updateInputValue(item.id, text)} placeholder={`Ingresa ${item.label}`} /> </View> </View> ))} <View style={styles.flex}> <View style={styles.ButtonAdd}> <Button title="Add input" color="#B13682" onPress={this.addInput} /> </View> <View style={styles.ButtonDelete}> <Button title="Delete input" color="#B13682" onPress={() => { // Delete the last added input (adjust if you want to delete specific ones) const lastInputId = this.state.measurements[this.state.measurements.length - 1].id; this.deleteInput(lastInputId); }} /> </View> </View> <View style={styles.otro}> <Button title="Send" color="#B13682" onPress={this.validate} /> </View> </View> </ScrollView> ); }
Key Notes:
- Unique IDs: We use
Date.now().toString()to generate unique IDs for each input, which makes deleting specific items straightforward. - State Immutability: All state updates use spread operators or map/filter to avoid mutating the original state, which is a best practice in React.
- Firebase Structure: Storing measurements as an object (instead of individual fields) lets you save all dynamic inputs without hardcoding field names.
- Customization: You can modify the
addInputfunction to let users input custom labels for new fields (e.g., using a modal or prompt).
内容的提问来源于stack exchange,提问作者fabianmeneses

