FaridSafi / react-native-gifted-form

📝 « One React-Native form component to rule them all »
MIT License
1.44k stars 214 forks source link

value prop returned from getValue (if available) after you delete all text in textinput #52

Open faceyspacey opened 8 years ago

faceyspacey commented 8 years ago

In short, if you're passing in the value prop it will continue to be returned from getValues and getValue for the given input after you delete all text in the input. The expected result is that it returns '';

A temporary a solution is to use onChangeText, but still then that means you need to unnecessarily add it to all your forms. It's inconsistent with the expected results. For example, if I have 2 characters: 'ab' and I delete one and then call getValue I'll get back a, but then if I delete a, you should get back '', but instead you will get back the string you passed in as the value prop.

I've searched the code and I can't for the life of me find where this mechanism to choose the value for this.props.value when what's entered is an empty string. It should be a quick fix for someone that knows.

faceyspacey commented 8 years ago

well, what's happening is widgetmixin's componentDidMount method is being called again when an input invalidates, and I'm not sure why that would require re-mounting. But when it is remounted it now uses the initial props again. In my case it doesn't make sense to store in redux the state onChangeText, but only when the form is saved. Otherwise, you have to maintain 2 sets of state: the unsaved state being worked on and the last previous valid state. Then you'd have to reconcile the 2 and only use the new "being worked on" state until the user leaves the page, and then when he returns use the correctly saved state, but then as soon as the state starts being edited again switch in the newly edited state. I'm honestly not even sure how to do this. It's just extremely incorrect when the form is otherwise maintaining the appropriate "pending state" for all use cases except when you remove all the text in an input and it weirdly remounts itself.

So in conclusion, componentDidMount has a major bug in widgetmixin and needs to be changed to prepare for this re-mounting. It seems to be written with the expectation that it sets its value from props.value on a true componentDidMount, not during this "re-mounting." The fix seems to simply be to check the store for a value like is done in the code directly below the group of called commented "get value from prop":

componentDidMount() {
    // get value from prop
    if (typeof this.props.value !== 'undefined') {
      this._setValue(this.props.value);
      return;
    }

    // get value from store
    var formState = GiftedFormManager.stores[this.props.formName];
    if (typeof formState !== 'undefined') {
      if (typeof formState.values[this.props.name] !== 'undefined') {
        this.setState({
          value: formState.values[this.props.name],
        });
        this._validate(formState.values[this.props.name]);
      }
    }
  },