Im trying to render a form dynamically using "for" loop, and its renders good but when I tried to change the value in a picker, it changed but it immediately changes to the default value, so what i need to do to fix this?
class Datos extends Component {
cotizadorData: any;
planesData: any;
dataStructure =
{
id: 1,
name: '',
lastName: '',
email: '',
documentNumber: '',
dateOfBirth: '',
age: '',
gender: 'M',
areaCode: '',
phoneNumber: '',
medicalObservation: 'Sin Observaciones'
};
emergencyContactDataStructure =
{
name: '',
email: '',
areaCode: '',
phoneNumber: ''
};
planCode: string = '';
departurePlaceCode: string = '';
arrivalPlaceCode: string = '';
passengersArray: Array = [];
additionalPassengersCount: number = 0;
additionalPassengersArray: Array = [];
additionalPassengersView: Array = [];
__isMounted: string = 'false';
mainPassengerAreaCodeRef: any;
emergencyContactAreaCodeRef: any;
apiKey: string = '';
xmlForOrder: string = '';
constructor(){
super();
this.state = {
showLoader: false,
countries : [ {
label: '',
value: ''
} ],
holderData: this.dataStructure,
additionalPassengers: [],
additionalPassengersView: [],
emergencyContact: this.emergencyContactDataStructure
};
}
async componentDidMount () : void {
this.setState({
showLoader: true
});
await AsyncStorage.setItem('dataComponentIsMounted', 'true');
this.apiKey = await AsyncStorage.getItem('apiKey');
this.xmlForCountries = getCountries(this.apiKey);
this.countries = await getOrbisDataServer(this.xmlForCountries);
this.processCotizadorData();
this.setState({
departurePlace: this.countries[0].description
});
this.formatArraysForPickers();
};
updateAsyncStorage = async() => {
this.__isMounted = await AsyncStorage.getItem('dataComponentIsMounted');
if(!isUndefinedOrNull(this.__isMounted))
{
if(this.__isMounted === 'true')
{
this.processCotizadorData();
}
}
};
processCotizadorData = async() => {
this.additionalPassengersCount = 0;
this.additionalPassengersArray = [];
this.cotizadorData = await AsyncStorage.getItem('cotizadorData');
this.planesData = JSON.parse(await AsyncStorage.getItem('planesData'));
if(!isUndefinedOrNull(this.cotizadorData))
{
this.cotizadorData = JSON.parse(this.cotizadorData);
this.additionalPassengersCount = (this.cotizadorData.youngs + this.cotizadorData.adults +
this.cotizadorData.semiSeniors + this.cotizadorData.seniors) - 1;
let id = 2;
for(let i = 0; i < this.additionalPassengersCount; i++)
{
this.additionalPassengersArray.push({
id: id,
name: '',
lastName: '',
email: '',
documentNumber: '',
dateOfBirth: '',
age: '',
gender: 'M',
areaCode: '',
phoneNumber: '',
medicalObservation: 'Sin Observaciones'
});
id++;
}
this.setState({
additionalPassengers: this.additionalPassengersArray
});
this.renderAdditionalPassengersForms();
}
};
setAdditionalPassengerGender = (additionalPassenger, value) => {
let additionalPassengersModified = [...this.state.additionalPassengers];
let index = additionalPassengersModified.findIndex(el => el.id === additionalPassenger.id);
additionalPassengersModified[index] = {...additionalPassengersModified[index], gender: value};
this.setState({
additionalPassengers: additionalPassengersModified
});
};
renderAdditionalPassengersForms = () => {
for(let i = 0; i < this.additionalPassengersArray.length; i++)
{
this.additionalPassengersView.push(
<View>
<Text style={[styles.normalFont, styles.label]}>SEX</Text>
<Picker
selectedValue={this.state.additionalPassengers[i].gender}
style={{height: 50, width: 100}}
onValueChange={(value) => {this.setAdditionalPassengerGender (this.additionalPassengersArray[i], value)}}>
<Picker.Item label="Male" value="M"/>
<Picker.Item label="Female" value="F"/>
</Picker>
</View>
)
}this.setState({
additionalPassengersView: this.additionalPassengersView
});
}
I expect to change the picker value for selected one.
Edited: I added the whole component
Since your UI has no issue pilling up views on this.additionalPassengersView
, I suppose renderAdditionalPassengersForms
is not called everytime the value in any of the additional passengers pickers change.
You problem is: selectedValue
on Picker has to be updated when you make a choice. Otherwise, the picker will roll back to its non-updated selected value, as the behavior you describe.
I use redux-form to manage my forms. But, assuming you don't want to use it, you can make a new component for the picker, putting the picker selected value on the state and updating this state on onValueChange callback