react-form-with-constraints icon indicating copy to clipboard operation
react-form-with-constraints copied to clipboard

Return the input state and form state using hooks

Open tkrotoff opened this issue 5 years ago • 1 comments

With v0.12, to stylize an input given its state (pending for example), you have to catch the events:

export class Input extends React.Component {
  [...]

  state: InputState = {
    field: undefined
  };

  componentWillMount() {
    this.context.form.addFieldWillValidateEventListener(this.fieldWillValidate);
    this.context.form.addFieldDidValidateEventListener(this.fieldDidValidate);
    this.context.form.addFieldDidResetEventListener(this.fieldDidReset);
  }

  componentWillUnmount() {
    this.context.form.removeFieldWillValidateEventListener(this.fieldWillValidate);
    this.context.form.removeFieldDidValidateEventListener(this.fieldDidValidate);
    this.context.form.removeFieldDidResetEventListener(this.fieldDidReset);
  }

  fieldWillValidate = (fieldName: string) => {
    // Ignore the event if it's not for us
    if (fieldName === this.props.name) {
      this.setState({ field: 'pending' });
    }
  };

  fieldDidValidate = (field: Field) => {
    // Ignore the event if it's not for us
    if (field.name === this.props.name) {
      this.setState({ field });
    }
  };

  fieldDidReset = (field: Field) => {
    // Ignore the event if it's not for us
    if (field.name === this.props.name) {
      this.setState({ field: undefined });
    }
  };

  [...]
}

There is probably a better story here thx to hooks.

const field = useField('fieldName');
return (
  <input className={field.state === 'PENDING' ? 'is-pending' : ''} />
);
enum FieldValidationState {
  Untouched,
  ValidationPending,
  ValidationPerformed
};

See https://www.google.com/search?q=field+validation+status

Work on field lifecycle: untouched => willValidate => didValidate (hasErrors, hasWarnings, hasInfos, isValid) => didReset

Related issues: #40

We should also do the same for the form itself:

const form = useForm(...);
if (form.state === 'VALID') ...
enum FormState {
  Untouched,
  ValidationPending,
  ValidationPerformed
};

Work on form lifecycle: untouched => willValidate => didValidate (hasErrors, hasWarnings, hasInfos, isValid) => didReset

Check for inspiration here: https://github.com/bluebill1049/react-hook-form

tkrotoff avatar Jun 16 '19 13:06 tkrotoff

Use case:

For a captcha with an image, an input and a button to check the entered matches the image. The input is required.

  • We want to turn the input red with ✕ mark if not filled
  • We don't want the input to be green with a ✓ if filled because the user could understand the text he entered matches the image

tkrotoff avatar Jun 21 '19 09:06 tkrotoff