React Native - Get input value only if state has changed

Viewed 609

I have a very simple form with two elements. One is a TextInput, the other one a DateTimePicker. I call this form by tapping on one element in a list of TouchableHighlight. After tapping, I send the index of the element I tapped and use it to get the object from an array.

When I open the edit form containing an Input and a dateTime, edit any of them and tap confirm my code works fine.

However if after I close this one, I open another one and edit only one of both fields, the other (non-modified) field will take the last saved value in the state variable. This value is the value for the previous modification, because since I did not updated this field, the state value for it's variable hasn't changed.

My question is how to avoid this? How can I detect which field changed and let the other remain the same. I could create a state variable that will change only if the field value changes. That is not the solution I'm looking for because what if I have 100 fields?

Below my code:

//Here I get the element the user tapped. 
const element = arrayOfElems[index]


/**
These are the current values of each element. I store them here instead of in a state,
because If I always use the state if the user makes no change, then the displayed 
values are replaced for those stored in the state.
**/
const defaultName = element.name;
const defaultTime = element.time;

//A state variable to determine if any field has been modified
const [edit, setEdit] = useState(false)

//Set a state variable for the name and time values of the selected element
const [nameInState, setNameInState] = useState(defaultName)
const [timeInState, settimeInState] = useState(defaultTime)


  /** My guess is my problem is here, because no matter which field
      I modify, I set the edit state to true. It's the way I came up to
      determine if the form had been modified. If I don't do this and 
      use the setState directly in the input, then if I save with no changes,
      the values are changed to the previous saved state.**/ 
  const updateValue = (value):string | number => {
    setEdit(true)
    if (typeof value == "number"){
      settimeInState(value)
      return timeInState
    }
    setNameInState(value)
    return nameInState
  }
  
  /** If the user has made no changes, I save the default values
      instead of those in the state variables. **/
  const getValue = (type) => {
    if(type === "time"){
      return edit ? timeInState : defaultTime
    }
    return edit ? nameInState : defaultName
  }

// This is the action when the user taps confirm
const updateInfoInDb = ():void => {
    if (typeof timeInState !== "number") { return }
    appoint.editSched(index, personId, {
      name: getValue("name"),
      time: getValue("time"),
    } as IAppointm)
      .then(() => {
        doStuff()
      })
      .catch((err) => {
        setLoading(false)
      })
      setEdit(false)
  }

return(
            <View style={Modals.styles.modalBody}>
            <Input
              inputContainerStyle={Inputs.outlined}
              defaultValue={defaultName}
              onChangeText={updateValue}
              errorStyle={Inputs.errorMessage}
              />
            <Text style={Modals.styles.label} tx="en.modifyTimeDate" />
            <TimePicker programTime={getValue("time")} updateTime={updateValue} />
            <DefaultButton
              action={updateInfoInDb}
              disabled={disabled}
              disabledStyle={"disabled"}
              loading={loading}
              size={"base"}
              style={"primary"}
              text={"common.confirm"}
            />
          </View>
)

This is the code for the <TimePicker/>

<DateTimePicker
 mode="time"
 display="default"
 style={styles.androidTimePicker}
 is24Hour={is24h()}
 value={programTimeToDate}
 onChange={updateTime}/>
0 Answers
Related