Using Form
Almost every web application implements the C.R.U.D. model. So far, we’ve gone over several ways to Read data from your API using powerful declarative React components. The ability to Create and Update data is the purpose of the <Form />
component.
The <Form />
component provides a way to …
- Use
Model
schemas to keep track of form fields - Use
Model
routes to avoid hard-coding API routes - Perform client-side form validations and populate error messages
- Create or update data in your JSON API
- Hook into form callbacks that give you granular control over data
…all while skipping a ton of boilerplate!
Contents
Basic Example
If you can read JSX, you can learn a lot about how the <Form />
component operates by viewing how it’s used. Here’s a basic example of the <Form />
component in a typical sign-up form.
import ReactiveRecord, { Form } from "reactiverecord"
const User = ReactiveRecord.model("User")
...
return (
<Form for={new User()}>
{fields => (
<Fragment>
<Input {...fields.full_name} />
<Input {...fields.email} />
<Input {...fields.password} />
<Button {...fields.submit}>Sign Up</Button>
</Fragment>
)}
</Form>
)
Generated | onSubmit() |
---|---|
| POST /users 201 Created
|
Amazing! Let’s talk about what’s written here.
- By passing in a
new User()
instance as thefor
prop, we’re telling the<Form />
component to expect fields based on theUser
model’s schema. - Because it’s a
new
user, it’s assumed the resource doesn’t exist, which means the appropriate form method isPOST
. - We know the route configuration from the model class, so the form action will be
/users
. - Like other Reactive Record components, the
<Form />
component expects a function as its child. The function received a form object, which contains properties that help build the individual form fields. We can pass those properties directly to our<Input />
components, which we’ll go over in detail later.
Available Props
Prop | Type | Description | Required |
---|---|---|---|
children | Function | Function receives one argument: a Reactive Record form object. It contains properties named after the given model’s schema, and is used to manage form controls within the form. You can read more about what’s available in the form object below. | Yes |
for | Model instance | Pass in the resource being acted upon. This resource must be an instance of a class which inherits from Model . Example: new User() . | Yes |
beforeValidation | Promise | Called before form validation occurs after form is submitted. The given Promise receives the form’s internal fields object, which contains refs to mounted form controls. At this point in the form submission, no data validation has occurred. You can use this callback as an opportunity to edit form values before validation occurs. The given Promise must be resolved in order to continue form submission. | No |
afterValidationFail | Function | Called after all validation has occurred, but at least one field has failed validation after form submission. The given function receives an object containing all field values. | No |
beforeSave | Promise | Called after form validation succeeds and the form is ready for final submission. The given Promise receives an object containing all field values which will be submitted. You can use this callback as an opportunity to cancel form submission and do something else with the form data, or to edit fields just before an API request is made. The given Promise must be resolved with the original or mutated form values object in order to continue form submission. | No |
afterSave | Function | Called after an API request succeeds with a successful HTTP status code (greater than 199 and less than 400). The function receives the latest version of the resource being acted upon. This callback is called immediately before the next action is dispatched, thereby triggering a re-render. | No |
afterRollback | Function | Called after an API request fails due to an HTTP status code (greater than or equal to 400), or an error that occurred while processing the response. The given function receives a resource when available or the resulting error. This callback is called immediately before the next action is dispatched, thereby triggering a re-render. | No |
builder | Function | Used to build field props for custom form controls. Read more about the builder API in the next guide. | No |
query | Object|String | Used to add extra parameters not in the model’s schema to the request body. The query can either be an object, which will be serialized, or a query string. Examples: { utm_source: 'google', utm_medium: 'cpc' } utm_source=google&utm_medium=cpc | No |
* | any | Any props given that are not listed above will be passed directly to the inner <form> DOM element, except onSubmit(), which is ignored. Example: className, aria-*. | No |
The Form Object
The function passed in as children for the <Form />
component receives an object containing properties used to build form controls within the form. The properties map directly to the form resource’s schema. For instance, if the schema for a model called Session
is:
Session.schema = {
username: String,
password: String
}
… the resulting form object would contain:
{
username: {…},
password: {…},
submit: {…},
submitting: false,
validating: false,
fieldsFor: ƒ()
}
There are additional properties in the above object that are not in the schema, which we will go over shortly. Let’s start with the first property, username
. It contains individual field props.
Field Props
The <Form />
component builds field props for each attribute in the schema. These field props can be passed directly to form controls to render the correct data. Here is a list of the default field props given for each schema attribute:
Attribute | Value |
---|---|
ref | Function needed to track the form control element. Pass directly to the form control. |
labelText | Text describing the form control. By default, this is the humanized name of the attribute. An attribute called email will by default have the label text “Email.” It can be overridden by configuring the model schema. |
defaultValue | Contains the default value for the attribute. If the resource is existing, expect the existing value to be present. Otherwise, the default value will be null or the default value set in the model schema. |
errorText | Contains the specific error text related to the form control, either from client-side validations or an API response. |
validators | If the attribute has validators, they will be present here. |
Submit Props
The form object contains a submit
property, which can be passed directly to a <button>
element, which submits the form. It contains the following attributes:
Attribute | Value |
---|---|
disabled | True only while the form is submitting or validating to prevent consecutive form submissions or “rage clicking.” |
children | The value is “Saving” while the form is submitting, and is otherwise undefined . Use this to easily override the button children while an API request is made. |
Other Form Object Properties
Attribute | Value |
---|---|
submitting | True only while an API request is made. |
validating | True only while field validations are occurring. |
fieldsFor | Function used to create fields for nested attributes. Learn more about using fieldsFor later. |