Recently, we refactored the React && Hook form component to make it usable and achieve the following goals

  • Configuration: Template less, configuration implementation form
  • Flexible structure: In addition to form ontology, can flexibly add a variety of auxiliary structures
  • Modularity: Forms can not only be used as part of a form, but can also be split out and used independently
  • Dynamic: The form can be added or subtracted dynamically
  • Linkage: The linkage between forms can be configured
  • Extensible: Forms require thousands of forms, and of course they must be extensible

Configuration change

The advantage of doing template less is that you can modify the logic, business and rendering in JS. In the case of complex form business, the template increases a lot of unnecessary work, and finally I hope the template is just a label reference

configuration

const config = {
  data: [
    {input...},
    {button onClick=responseClick...}
  ]
}

function responseClick(){
  form.append({input...})
}
Copy the code

The template

<Form data={config} />
Copy the code

structure

Single form

A complete form, in addition to the form ontology, and other attributes such as error message, whether to select, form title and so on, requires some auxiliary structures to help express them, as shown in the following figure

The image above is just a simple schematic, and should also require UI level assistance such as the small eyes of the password, the small arrows of the drop-down menu, and so on. Helper structures such as the one shown above can be passed in by configuration, displayed when values are present and not displayed when no values are present, and the accompanying API is required to invoke them as required

The configuration code

const input = {type: 'text'.id: 'uniq-id'.value: 'hello'.className: '... '}
Copy the code

The composite form

What is a composite form, such as a provincial form, which consists of multiple individual forms and supports various types of forms, as shown in the following figure

The configuration code

const input = [
  {title: 'Username'.type: 'text'.id: 'uniq-id'.value: '... '.className: '... '},
  {title: 'that'.type: 'text'.id: 'uniq-id'.value: '... '.className: '... '}]Copy the code

Group form

Multiple composite forms or single forms are mixed together to form an independent part of the complete form. Multiple groups of forms are combined to form the complete form, as shown in the following figure

The configuration code

const input = {
  title: 'Group form'.input: [{form -1}, {form -2}, {form -3]}},Copy the code

Complete the form

The complete form consists of multiple group forms, as shown in the following figure

The configuration code

data: [
  // Form group-1
  {
    title: 'Form Group 1- Title'.input: [Form -1, the form -2. ] },// Form group-2
  {
    title: 'Form Group 2- Title'.input: [Form -1, the form -2. ] },... ]Copy the code

modular

Once we have form parts of various configurations, we can configure them to combine or use them individually (in different scenarios)

Used alone

const config = {title: 'Single form'.value: '... '} 
const Text = <form.Text data={config} />
Copy the code

Use a combination of

const config = [
  {
    title: 'name'.type: 'text'.value: '... '
  },
  {
    title: 'career'.type: 'text'.value: '... '},]const group = <form.Group data={config} />
Copy the code

dynamic

Configuration is dead, how to configure the output of what structure, but does not meet the requirements of the product. Many scenarios require dynamic addition and subtraction of forms while maintaining the data that was originally filled in. Take the group form as an example

const config = [
  {
    id: 'id-1'.title: 'name'.type: 'text'.value: '... '
  },
  {
    id: 'id-2'.title: 'career'.type: 'text'.value: '... '},]const groupJSX = <form.Group gid='g-1' data={config} />
const group = form.getGroup('g-1')
Copy the code

Append Appends the configuration

const newConfig = {
  id: 'id-new'.title: '... '.type: ' '.value: ' '
}
group.append(newConfig)
Copy the code

Delete Delete configuration

group.delete({id: 'id-2'})
Copy the code

Insert Insert configuration

group.insert(1, {title: 'Insert form'.type: ' '.value: ' '})
Copy the code

This is just an example of the API methods that allow you to make flexible changes to the form

linkage

In many scenarios, linkage between forms is required. You can configure the linkage operation by introducing a linkage attribute union to establish the relationship between the observer and the observed

const textConfig = {id: 'id-1'.title: '... '.type: 'text'.value: '... '}
const textWatcher = {
  title: 'Observer Form'.id: 'watcher'.type: 'text'.value: '... '.union: [
  	'id-1'.'onChange'.function(value){
      /* do something */}}]Copy the code

The union attribute contains observation object, observation object method name and response method. The relationship between different forms is established through the union attribute. When the value of ID-1 form is changed, the response method of the observer will be triggered

extensible

A form component can register a new form through the Register method to accommodate different form interaction requirements, as in the following example

// Cell supports text forms by default (partial)
// Register a custom text form to replace the built-in text form with a richer form type
function TextInput(props) {
  let$props = { ... props }; $props.store =null;
  $props.registeroptions = null;
  return <input {.$props} / >;
}

register(
  "Text"["text"."number"."telephone"."password"."color"."email"."date"."time"."range"."month"
  ],
  TextInput
);

const textConfig = {type: 'month'}
const form = <form.Text data={textConfig} />
Copy the code

The example above defines a text form. When type falls within the scope of the custom form, the react method component is used to output the structure. We can also define API methods for this method component to flexibly control the form

Write in the last

After more than a month of development, a version of the form component has been completed, the basic implementation of the above functions

React /hook form component