nicovg15
nicovg15

Reputation: 25

how can i get the value of this inputs in react native?

so i cannot manage to get the value of any of my inputs, and the only thing is working for me is grabbing them inside render but just getting letter by letter. I want to use the same state for all of them (formData) so when I submit I can grab all the values in an unique object

Any recommendation to solve it??

export default class TimeOff extends Component {
constructor(props) {
    super(props);
    this.state = {
      selectedStartDate: null,
      selectedEndDate: null,
      selectedValue: '',
      formData: '',
    };
  }

  handleSubmit = event =>  {
    event.preventDefault()
    console.log(this.state.formData)

      render(){
    Moment.locale('en')
    const { selectedStartDate, selectedEndDate, formData, selectedValue } = this.state;
    const minDate = new Date();
    const maxDate = new Date(2090, 1, 1);
    const startDate  =  selectedStartDate ? selectedStartDate.toString() : '';
    const endDate = selectedEndDate ? selectedEndDate.toString() : '';

    return(
    <ScrollView showsVerticalScrollIndicator={false}>
        <Navbar />
        <Text style={styles.hOneTimeOff}>Schedule time off</Text>
        <View style={styles.timeOffWrapper}>
            <TextInput
                name="firstname"
                style={styles.timeOffInput}
                mode='outlined'
                placeholder="First name"
                value={formData.firstname}
                onChangeText={firstname => this.setState({formData: firstname})}
            />
            <TextInput
                name="lastname"
                style={styles.timeOffInput}
                mode='outlined'
                placeholder="Last name"
                value={formData.lastname}
                onChangeText={lastname => this.setState({formData: lastname})}
            />
            <Picker 
            name="role"
            style={styles.timeOffPicker} 
            value={formData.role}
            selectedValue={selectedValue}
            onValueChange={role => this.handlePicker(role)}
            >
                <Picker.Item label="What's your role?" value=''/>
                <Picker.Item label='Warehouse' value='Warehouse'/>
                <Picker.Item label='Bakery' value='Bakery'/>
                <Picker.Item label='Dry pack' value='Dry pack'/>
                <Picker.Item label='Dry mix' value='Dry mix'/>
                <Picker.Item label='Maintenance' value='Maintenance'/>
                <Picker.Item label='Mechanical' value='Mechanical'/>
            </Picker>
            <View style={styles.container}>
                <CalendarPicker
                    startFromMonday={true}
                    allowRangeSelection={true}
                    minDate={minDate}
                    maxDate={maxDate}
                    selectedDayColor="#00486D"
                    selectedDayTextColor="#FFFFFF"
                />
                <View>
                    <Text>Start Date: {Moment(startDate).format("M/D/YYYY")}</Text>
                    <Text>End Date: {Moment(endDate).format("M/D/YYYY")}</Text>
                </View>
            </View>
            <TouchableOpacity style={styles.btnTimeOff} onPress={this.handleSubmit}>
                <Text style={styles.btnTextTimeOff}>Submit</Text>
            </TouchableOpacity>
        </View>
    </ScrollView>
    )
}

}

Upvotes: 0

Views: 74

Answers (3)

Michael Alan Cohen
Michael Alan Cohen

Reputation: 86

Your on change function is always overwriting your entire previous state.

You can use the setState function with a callback and the spread operator to update the state without losing previous state like so:

  1. First create and function for onTextChange:
const handleChange = (name, value) => {
    this.setState(
        (previousState) => {
            let previousFormData = previousState.formData;
            return {
                ...previousState,
                formData: {
                    ...previousFormData,
                    [name]: value
                }
            }
        }
    )
}
  1. Then Update you component like so:
export default class TimeOff extends Component {
constructor(props) {
    super(props);
    this.state = {
      selectedStartDate: null,
      selectedEndDate: null,
      selectedValue: '',
      formData: '',
    };
  }

  handleSubmit = event =>  {
    event.preventDefault()
    console.log(this.state.formData)
  }

    handleChange = (name, value) => {
        this.setState(
            (previousState) => {
                let previousFormData = previousState.formData;
                return {
                    ...previousState,
                    formData: {
                        ...previousFormData,
                        [name]: value
                    }
                }
            }
        )
    }
    render(){
    Moment.locale('en')
    const { selectedStartDate, selectedEndDate, formData, selectedValue } = this.state;
    const minDate = new Date();
    const maxDate = new Date(2090, 1, 1);
    const startDate  =  selectedStartDate ? selectedStartDate.toString() : '';
    const endDate = selectedEndDate ? selectedEndDate.toString() : '';

    return(
    <ScrollView showsVerticalScrollIndicator={false}>
        <Navbar />
        <Text style={styles.hOneTimeOff}>Schedule time off</Text>
        <View style={styles.timeOffWrapper}>
            <TextInput
                name="firstname"
                style={styles.timeOffInput}
                mode='outlined'
                placeholder="First name"
                value={formData.firstname}
                onChangeText={text => this.handleChange("firstname", text)}
            />
            <TextInput
                name="lastname"
                style={styles.timeOffInput}
                mode='outlined'
                placeholder="Last name"
                value={formData.lastname}
                onChangeText={text => this.handleChange("lastname", text)}
            />
            <Picker 
            name="role"
            style={styles.timeOffPicker} 
            value={formData.role}
            selectedValue={selectedValue}
            onValueChange={role => this.handlePicker(role)}
            >
                <Picker.Item label="What's your role?" value=''/>
                <Picker.Item label='Warehouse' value='Warehouse'/>
                <Picker.Item label='Bakery' value='Bakery'/>
                <Picker.Item label='Dry pack' value='Dry pack'/>
                <Picker.Item label='Dry mix' value='Dry mix'/>
                <Picker.Item label='Maintenance' value='Maintenance'/>
                <Picker.Item label='Mechanical' value='Mechanical'/>
            </Picker>
            <View style={styles.container}>
                <CalendarPicker
                    startFromMonday={true}
                    allowRangeSelection={true}
                    minDate={minDate}
                    maxDate={maxDate}
                    selectedDayColor="#00486D"
                    selectedDayTextColor="#FFFFFF"
                />
                <View>
                    <Text>Start Date: {Moment(startDate).format("M/D/YYYY")}</Text>
                    <Text>End Date: {Moment(endDate).format("M/D/YYYY")}</Text>
                </View>
            </View>
            <TouchableOpacity style={styles.btnTimeOff} onPress={this.handleSubmit}>
                <Text style={styles.btnTextTimeOff}>Submit</Text>
            </TouchableOpacity>
        </View>
    </ScrollView>
    )
}

This also preserves the other variables in your state object.

Upvotes: 1

Piyush
Piyush

Reputation: 609

onChangeText={firstname => this.setState({formData: {...this.state.formData, firstname}})}

onChangeText={lastname=> this.setState({formData: {...this.state.formData, lastname}})}

Use this to update the nested state object, it will keep old values and would also update new one

Upvotes: 0

D10S
D10S

Reputation: 1559

You keep overwriting the "formData" state value.

Since you want it to act as an object (with entries: "firstname", "Lastname", etc) when you setState you should wrap the entries with curly brackets like this:

...
onChangeText={firstname => this.setState({formData: {firstname}})}
...
onChangeText={lastname=> this.setState({formData: {lastname}})}
...

Upvotes: 0

Related Questions