Skip to content

Higher Order Components

Michal Katanski edited this page Oct 14, 2017 · 2 revisions

Types

ValidationResult

Contains list of errors or warnings. For synchronous validation key is a number. For asynchronous validation key is a string = async.

type ValidationResult = {
  [key: string | number]: string,
}

FormData

type FormData = {
  errors: {
    [inputName: string]: ValidationResult
  },
  warnings: {
    [inputName: string]: ValidationResult
  },
  isValid: boolean,
  isPristine: boolean,
  isSubmiting: boolean,
  isValidating: boolean,
  values: FormValues,
}
  • errors: contains list of messages returned by inputs validation for each input in the form
  • warnings: the same as for errors but contains warning messages
  • isValid: true if there is no validation error in the form
  • isPristine: true if form values are unchanged from its initial state. Changes to false on first onBlur event.
  • isSubmiting: true if form is trying to submit its values at the moment
  • isValidating: true if form is performing asynchronous validation at the moment
  • values: list of form values

FormValues

Contains a list of values for each input in the form.

type FormValues = {
  [inputName: string]: any,
}

InputEventData

type InputEventData = {
  ...FormData,
  inputName: string,
  value: any,
}
  • inputName: name of the input. Usually the one which is dispatching an event.
  • value: current value of the input

StrapForm()

function(WrappedComponent: ReactElement): <StrapForm>

Creates a new <StrapForm> component which manages all children inputs. Each input should be an instance of StrapInput.

<StrapForm>

Manages all components and allows you to perform global operations on them, such as validating all components in case you try to send a form and collect their values.

To make this possible, each component that is to be managed must be an instance of the StrapInput component.

StrapForm also provides contextual methods for listening and executing events (Context Events). Context events are the main mechanism on which forms are based. With this solution, you can freely write your own components that are managed via StrapForm. This solution also optimizes code by avoiding unnecessary rendering of elements.

Props

Below is a list of default StrapForm properties. These properties are not passed to WrappedComponent. Any additional property given to the instance of the StrapForm will be passed directly to WrappedComponent.

props: {
    children: any,
    onSubmit: function async (data: FormData): void,
    onInputBlur?: function(data: InputEventData): void,
    onInputChange?: function(data: InputEventData): void,
}

Note: custom type structures are described here.

onInputBlur

Triggered every time an input looses its focus within the form.

onInputChange

Triggered every time an input changes its value within the form.

onSubmit

Triggered when form is going to be submitted and there is no errors.

Context

context: {
  listenTo: function(eventName: string, handler: function): void,
  dispatchEvent: function(eventName: string, eventData: Object): Array,
}

listenTo

Create new listener for specific event. List of available events is here.

dispatchEvent

Dispatch an event. Every listener for that event will recieve object with event data. Also it returns an array with returning values of each listener.

<WrappedComponent>

Usually it should be an instance of <form> component.

Props

props: {
    children: any,
    handleSubmit: function async (event: Event): void,
}

handleSubmit

Should be triggered when form is going to be submitted. For example:

<form onSubmit={ handleSubmit } />

StrapInput()

function(WrappedComponent: ReactElement): <StrapInput>

As the name implies, StrapInput creates a component for entering data by the user. It is also responsible for the validation of this data.

<StrapInput>

StrapInput should be a child of the StrapForm component.

Props

Below is a list of default StrapInput properties. These properties are not passed to WrappedComponent. Any additional property given to the instance of the StrapInput will be passed directly to WrappedComponent.

props: {
    name: string,
    asyncValidation?: function (value: any, values: FormValues): async function(),
    children?: any,
    disabled?: boolean,
    initialValue?: any,
    readOnly?: boolean,
    validate?: Array,
    warn?: Array,
}

Note: custom type structures are described here.

name

Name of the input. It will be visible in form values.

asyncValidation

Accepts method wich should return a promise which will be invoked on asynchronous validation. The promise should trigger an error with message describing invalid status.

Two arguments are passed to the method:

  • value which is a current input value
  • values all values for each input in the form

disabled

True if input has to be considered as disabled. Disabled input will not be validated.

initialValue

Set initial value for the input.

readOnly

True if input has to be considered as read only. Read only input will not be validated.

validate

An array of error validators. Each validator is a method which should return undefined if the validation is correct or string with message describing invalid status.

To each method are passed two arguments:

  • value which is a current input value
  • values all values for each input in the form
  function (value: any, values: FormValues): string | undefined

warn

An array of warning validators. Each validator is a method which should return undefined if the validation is correct or string with message describing invalid status. Form with warnings is considered as valid.

To each method are passed two arguments:

  • value which is a current input value
  • values all values for each input in the form
  function (value: any, values: FormValues): string | undefined

<WrappedComponent>

Props

props: {
    children: any,
    input: {
      disabled: boolean,
      id: string,
      name: string,
      onBlur: function (event: Event),
      onChange: function (event: Event),
      readOnly: boolean,
      value: any,
    },
    hasErrors: boolean,
    hasWarnings: boolean,
    errors: ValidationResult,
    warnings: ValidationResult,
    touched: boolean,
    isValidating: boolean,
}

input

Object containing basic input properties. Usually can be passed directly to the <input /> component.

For example:

<input { ...input } />

hasErrors

True if input has any validation error

hasWarnings

True if input has any validation warning

errors

List of validation errors

warnings

List of validation warnings

touched

True if input has lost focus

isValidating

True if input performs asynchronous validation