Newbie here, I have a page where a user adds and removes input forms by pressing an add/remove button. Each <InputCard/>
item has a few <TextInput/>
fields. I need changes to these <InputCard/>
items to change the state in the parent component. When the <TextInput/>
values change in each/any of the <InputCard/>
items, I need this change reflected in the parent formState
. Code is below:
InputScreen.js
import React, { useState } from 'react';
import { View, StyleSheet, ScrollView, FlatList } from 'react-native';
import { Button, Caption } from 'react-native-paper';
import InputCard from '../components/InputCard';
const InputScreen = props => {
const [inputList, setInputList] = useState([]);
const [formState, setFormState] = useState([]);
const addInput = () => {
setInputList(inputList.concat(<InputCard key={inputList.length} />));
setFormState([
...formState,
{
id: inputList.length,
substance: "",
amount: "",
measure: ""
},
]);
};
const handleInputChange = () => {
// each card has 3 input fields and needs to update the corresponding values in formState
// where the InputCard key and formState id are corresponding
};
const removeLastInput = () => {
if (inputList.length > 0) {
const lastindex = inputList.length - 1;
setFormState(formState.filter((item, index) => index !== lastindex));
setInputList(inputList.filter((item, index) => index !== lastindex));
}
};
return (
<ScrollView>
<View style={styles.col}>
<View style={styles.row}>
<Caption>What substances are you using?</Caption>
</View>
<View style={styles.row}>
<View>
{inputList}
</View>
</View>
<View>
<View style={styles.col}>
<Button title='Add' onPress={addInput}>Add</Button>
</View>
<View style={styles.col}>
<Button title='Remove' onPress={removeLastInput}>Remove</Button>
</View>
</View>
</View>
</ScrollView>
)
};
const styles = StyleSheet.create({
container: {
backgroundColor: '#c1f5f5',
paddingVertical: 20,
paddingHorizontal: 20
},
col: {
flexDirection: 'column',
paddingVertical: 10,
},
row: {
flexDirection: 'row',
},
rowright: {
flexDirection: 'row',
justifyContent: 'flex-end'
},
half : {
width: '50%',
paddingRight: 5,
},
quarter : {
width: '25%',
paddingHorizontal: 5,
},
quarterlast : {
width: '25%',
paddingLeft: 5,
},
third : {
width: '33%',
paddingHorizontal: 5,
},
thirdlast : {
width: '33%',
paddingLeft: 5,
},
substanceconfig : {
backgroundColor: '#E1F7F7',
fontSize: 12,
},
textfield : {
borderColor: '#1e5c64',
borderWidth: 2,
},
dropdown: {
height: 60,
backgroundColor: '#ffffff',
borderColor: '#1e5c64',
borderRadius: 7,
borderWidth: 1,
padding: 14
},
iconbutton: {
backgroundColor: '#1e5c64',
color: '#ffffff',
},
slider: {
flex: 1,
height: 60
},
flex1: {
flex: 1
}
});
export default InputScreen;
InputCard.js
import React from "react";
import { View, StyleSheet } from 'react-native';
import { Caption, Card, TextInput } from "react-native-paper";
const InputCard = (props, { formState, handleChange }) => {
const key = props.key;
return (
<View>
<Card>
<Card.Content>
<Caption>Item {key}</Caption>
<View style={styles.row}>
<View style={styles.half}>
<TextInput
label="substance"
value={formState[key].substance}
onChangeText={handleChange} // change needs to be made from here to parent
mode="outlined"
right={<TextInput.Icon name="pill" />}
style={styles.textfield}
/>
</View>
<View style={styles.quarter}>
<TextInput
label="amount"
value={formState[key].amount}
onChangeText={handleChange}
mode="outlined"
keyboardType="number-pad"
/>
</View>
<View style={styles.quarterlast}>
<TextInput
label="measure"
value={formState[key].measure}
onChangeText={handleChange}
mode="outlined"
/>
</View>
</View>
</Card.Content>
</Card>
</View>
);
}
export default InputCard;
const styles = StyleSheet.create({
container: {
backgroundColor: '#c1f5f5',
paddingVertical: 20,
paddingHorizontal: 20
},
col: {
flexDirection: 'column',
paddingVertical: 10,
},
row: {
flexDirection: 'row',
},
rowright: {
flexDirection: 'row',
justifyContent: 'flex-end'
},
half : {
width: '50%',
paddingRight: 5,
},
quarter : {
width: '25%',
paddingHorizontal: 5,
},
quarterlast : {
width: '25%',
paddingLeft: 5,
},
third : {
width: '33%',
paddingHorizontal: 5,
},
thirdlast : {
width: '33%',
paddingLeft: 5,
},
substanceconfig : {
backgroundColor: '#E1F7F7',
fontSize: 12,
},
textfield : {
borderColor: '#1e5c64',
borderWidth: 2,
},
dropdown: {
height: 60,
backgroundColor: '#ffffff',
borderColor: '#1e5c64',
borderRadius: 7,
borderWidth: 1,
padding: 14
},
iconbutton: {
backgroundColor: '#1e5c64',
color: '#ffffff',
},
slider: {
flex: 1,
height: 60
},
flex1: {
flex: 1
}
});
handleInputChange
in the child component, so right now theonChangeText
in theInputCard
is doing nothing.