
Security News
Axios Supply Chain Attack Reaches OpenAI macOS Signing Pipeline, Forces Certificate Rotation
OpenAI rotated macOS signing certificates after a malicious Axios package reached its CI pipeline in a broader software supply chain attack.
react-proforma
Advanced tools
React Proforma helps you build simple to complex web forms with ease in React. -- Simplicity where you want it. Flexibility where you need it.
Easily manage multiple form fields, validation, focus handling, and form submission. Use custom components (styled with css-in-js or from a UI library) or standard react elements anywhere you like. React Proforma is a complete form-solution that has been performance-optimized, is fully documented, and will make building your next React web form a breeze!
Proforma component API for details.Install using npm:
npm install react-proforma
Or yarn:
yarn add react-proforma
We'll start by building up a very basic, no-frills example with a single field and a submit button, just to give you a feel for what's going on. After that, I'll demonstrate code that is more like what you would normally use, including using React Proforma's custom form elements that are all hooked up internally.
Please note:
import React from 'react';
import { Proforma } from 'react-proforma';
class DemoForm1 extends React.Component {
renderForm(proformaBundle) {
/* to be filled in shortly */
}
render() {
return (
<Proforma>
{this.renderForm}
</Proforma>
);
}
}
render method is returning the Proforma component, and inside that is a reference to a function that I've called renderForm (which is currently empty).renderForm is the bundle of methods and properties you will need for your form to function. I've assigned this argument the name proformaBundle.this.renderForm! This is a function reference, not a function invocation.config and handleSubmit props to the Proforma componentimport React from 'react';
import { Proforma } from 'react-proforma';
class DemoForm1 extends React.Component {
renderForm(proformaBundle) {
/* to be filled in shortly */
}
render() {
return (
<Proforma
config={{
initialValues: {
field1: ''
}
}}
handleSubmit={(values) => {
console.log('The form has been submitted!', values);
}}
>
{this.renderForm}
</Proforma>
);
}
}
Proforma.config accepts an object (note the double curly braces) with one required property (initialValues) and a few optional properties (we'll learn more about those later).
initialValues is a required property, whose value must be an object, whose properties must correspond with the names of your form fields (i.e. name, email, password, etc.), and whose values are the initial value you'd like to set for each respective form field.'' (empty string).initialValues, it will be ignored, and empty string '' will be used.Proforma.handleSubmit is any function you want to have executed when the form is submitted. See the api for details, including what arguments are passed to your handleSubmit function on execution.renderForm isn't returning anything. Let's fix that next.renderFormNOTE: This is going to look ugly, but React Proforma's custom form elements will clean this all up very quickly! I just wanted to show you the manual set up first.
import React from 'react';
import { Proforma } from 'react-proforma';
class DemoForm1 extends React.Component {
renderForm(proformaBundle) {
const {
values,
handleSubmit,
handleChange,
handleFocus,
handleBlur
} = proformaBundle;
return (
<form onSubmit={handleSubmit}>
<input
type="text"
name="field1"
value={values.field1}
onChange={handleChange}
onFocus={handleFocus}
onBlur={handleBlur}
/>
<button type="submit">Submit</button>
</form>
);
}
render() {
return (
<Proforma
config={{
initialValues: {
field1: ''
}
}}
handleSubmit={(values) => {
console.log('The form has been submitted!', values);
}}
>
{this.renderForm}
</Proforma>
);
}
}
values, handleSubmit, handleChange, handleFocus, and handleBlur from proformaBundle.
proformaBundle.renderForm then returns a regular React form element.form and input elements, set the name prop on the input element to be 'field1', and hook up the value prop of the input to values.field1.At this point, we have a fully functioning form. The input is completely controlled, and you can submit the form by clicking the submit button (your console should display the message "The form has been submitted!", followed by the form values).

Check out the complete code for this form here.
Now that you've seen the nuts and bolts, let's clean it up and create a more complete example, with multiple fields and validation.
Introducing Form, Field, and Submit
We'll create a sign-up form with name, email address, and password fields to start.
import React from 'react';
import './DemoForm2.css';
import { Proforma, Form, Field, Submit, Debug } from 'react-proforma';
class DemoForm2 extends React.Component {
renderForm() {
return (
<div className="outer-wrapper">
{/* === FORM STARTS HERE === */}
<Form>
<div className="field-row">
<label htmlFor="name-field">Name:</label>
<Field
name="name"
type="text"
className="form-field"
id="name-field"
placeholder="E.g. Billy Bob"
/>
</div>
<div className="field-row">
<label htmlFor="email-field">Email:</label>
<Field
name="email"
type="text"
className="form-field"
id="email-field"
placeholder="E.g. billy@bob.com"
/>
</div>
<div className="field-row">
<label htmlFor="password-field">Password:</label>
<Field
name="password"
type="password"
className="form-field"
id="password-field"
/>
</div>
<Submit className="submit-button" />
</Form>
{/* === FORM ENDS HERE === */}
<div className="debug-wrapper">
{/* DEBUG COMPONENT */}
<Debug />
</div>
</div>
);
}
render() {
return (
<Proforma
config={{
initialValues: {
name: '',
email: '',
password: ''
}
}}
handleSubmit={(values) => {
console.log('The form has been submitted!', values);
}}
>
{this.renderForm}
</Proforma>
);
}
}
With some styling divs here and there, this code produces the following form:
(Grab the css file if you want to follow along exactly.)

NOTE: That window you see on the right is a Debug component I made in case you ever want to see your form's current state (i.e. values/errors/touched). Just import { Debug } from 'react-proforma' and insert the component anywhere inside the <Proforma>...</Proforma> tree.
The styling divs clutter things up a little, but I want you to just focus on the props passed to the Proforma component, as well as the Form (capital 'F') component inside the renderForm method.
config prop. Inside config is an object with a single property (for now) called 'initialValues', which contains the names of all the form fields our form is going to have, and their respective initial values.handleSubmit is again going to just console log our values.renderForm: Form, Field, and Submit
Form, Field, and Submit components imported from React Proforma.Field, all you have to do is pass in a name (that corresponds with one of the keys on your initialValues object) and a type (defaults to "text") as props, along with whatever other props you'd want passed down to the input element that will be returned (e.g. id, className, style, placeholder, maxLength, etc.)See an example that shows each React Proforma component in action.
Alright, so everything looks good, but we're going to need some validation.
Thankfully, React Proforma makes that almost too easy!
Enter the validationObject.
First, let's do it the long way:
<Proforma
config={{
initialValues: {
name: '',
email: '',
password: ''
},
validationObject: {
name: (values) => {
const { name } = values;
const errors = [];
if (name.length === 0) {
errors.push('This field is required.');
}
if (!/^[a-zA-Z\s]*$/.test(name)) {
errors.push('Your name can only contain letters and spaces.');
}
if (errors.length > 0) {
return errors;
}
return null;
}
}
}}
handleSubmit={(values) => {
console.log('The form has been submitted!', values);
}}
>
{this.renderForm}
</Proforma>
So what's going on here.
validationObject is another property on the object passed to the config prop. Here, the keys are one of the form field names (I used the 'name' form field here), and the values are a function which accepts all of the current form values, and returns either an array of strings or null.values, set up an empty errors array, and then run two validation tests on 'name':
null is returned.So, obviously this is a lot of typing. This is why I created a field validation helper called fieldValidator. Simpy import it: import { fieldValidator } from 'react-proforma', and use it to produce the same logic as above:
validationObject: {
name: (values) => {
return fieldValidator(values.name)
.required()
.regex(/^[a-zA-Z\s]*$/, 'Your name can only contain letters and spaces.')
.end();
}
}
fieldValidator the value you want to validate (in this case, it's 'values.name'), and then chain on whatever validation methods you want..required() and .regex().regex() call.fieldValidator API for all of the methods available to you.NOTE: You must add .end() to the end of the fieldValidator chain, and you must return the entire chain from the function! (I.e. return fieldValidator(values.name) ..... .end())
With this new tool, let's go ahead and add email and password validation in just a few seconds:
validationObject: {
name: (values) => {
return fieldValidator(values.name)
.required()
.regex(
/^[a-zA-Z\s]*$/,
'Your name can only contain letters and spaces.'
)
.end();
},
email: (values) => {
return fieldValidator(values.email)
.required()
.email()
.end();
},
password: (values) => {
return fieldValidator(values.password)
.required()
.regex(
/^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.{8,})/,
'Please enter a stronger password!'
)
.end();
}
}
NOTE: I pass the entire values object to each validation field so that you can access other values if that's what your validation requires. For more information, see the fieldValidator API.
Now we can take our form for a spin. Enter valid and invalid values, and see the 'Errors' object update in the Debug display.
For example:

NOTE: The 'touched' value for each field name turns true when a field receives and then loses focus. This is useful for displaying errors to the user, which is typically done only if 'touched' is true for that field name.
So this is all working quite nicely. But let's go ahead and try something a little more challenging, and see how React Proforma performs.
Let's say at this point we decide to add a second password field. That means we have to add a new field to our form, as well as attempt cross-field validation to make sure the passwords match. Once again, React Proforma makes it all easy.
Let's start by updating our form.
Add the following to your Form inside renderForm, before the Submit button:
<div className="field-row">
<label htmlFor="password2-field">Re-enter Password:</label>
<Field
name="password2"
type="password"
className="form-field"
id="password2-field"
/>
</div>
NOTE: The 'name' I used for this new field is 'password2'.
And update your initialValues object:
initialValues: {
name: '',
email: '',
password: '',
password2: ''
}
REMINDER: All form field names must be present in the Proforma.config.initialValues object, or it won't be included in any of React Proforma's functionality.
Now we need to add validation to 'password2' to make sure it matches 'password'.
Add the following property to your Proforma.config.validationObject:
password2: (values) => {
return fieldValidator(values.password2)
.required()
.custom(() => {
if (values.password2 !== values.password) {
return 'Your passwords must match exactly!';
}
})
.end();
}
Here we are making use of the custom() method chained to fieldValidator(). custom() takes a function as it's sole argument, which will be executed by Proforma during validation. If your function returns a string value, that value will be added to the current error messages for that field.
But we can make things even more concise in this case, by making use of the .equals() method:
password2: (values) => {
return fieldValidator(values.password2)
.required()
.equals(values.password, 'Your passwords must match exactly!')
.end();
}
(See the docs for all available chaining methods and their specific signatures.)
And that's all it takes to perform cross-field validation with React Proforma!
Here's what we've created so far:

The normal way of displaying errors in React is to write up some conditional checks inside your jsx that looks something like:
<div>
{touched.email && errors.email &&
errors.email.map((error) => ...) /* return component that displays error */
}
</div>
But that's kind of ridiculous to have to do for every single form field.
Enter fieldError()
Use it like this:
import { fieldError } from 'react-proforma';
Create a component that will receive each individual error message as its only prop. For example:
function FieldError(props) {
return <p className="field-error">{props.error}</p>;
}
Under each field row, add the following:
{fieldError('<FIELD NAME>', FieldError)}
As in:
<div className="field-row">
<label htmlFor="name-field">Name:</label>
<Field
name="name"
type="text"
className="form-field"
id="name-field"
placeholder="E.g. Billy Bob"
/>
</div>;
{fieldError('name', FieldError)} /* <--- */
NOTE: You could insert fieldError() anywhere of course.
And just like that we have:

Check out the complete code for this form here.
There's a lot more built into React Proforma, including other pre-wired components (Select, Checkbox, Radio, Textarea, and Reset), using custom components (like from a UI library or created by a css-in-js library, or just components you've created yourself) instead of standard React elements, and giving you access to more of your form's functionality through the methods and properties inside the ProformaBundle.
Browse the API to learn about everything that React Proforma offers you, and check out some more examples.
This entire library was written in Typescript, so in addition to being fully typed, I also take full advantage of Typescript's other features wherever possible.
Usage in Typescript is pretty much the same as it is in vanilla JS, with two notable exceptions:
The Proforma component is a generic class, so you just have to pass in the type that represents your form values, and Proforma propogates that around wherever possible:
type FormValues = {
name: string;
email: string;
password: string;
newsletter: boolean;
};
/* Skip to component render method */
render() {
return (
<Proforma<FormValues>
config={{...}}
handleSubmit={() => {...}}
>
{this.renderForm}
</Proforma>
);
}
If you didn't know how to pass in a type variable to a component in JSX before, now you know!
In your renderForm method (or whatever function returns your form mark-up), in order to have your proformaBundle argument fully typed, you have to import ProformaBundle, which is a generic type that expects your FormValues again as a type variable. As in:
import { ProformaBundle } from 'react-proforma';
type FormValues = {
name: string;
email: string;
password: string;
newsletter: boolean;
};
/* Skip to renderForm method */
renderForm(proformaBundle: ProformaBundle<FormValues>) {
return (
/* form markup */
);
}
Or with in-line destructuring:
renderForm({
values,
errors,
touched,
handleSubmit,
handleReset,
/* whatever else you need from ProformaBundle */
}: ProformaBundle<FormValues>) {
return (
/* form markup */
);
}
Very often you will likely want to use custom components or UI library components instead of standard React form elements. React Proforma makes this very easy to use.
Here's an example of how to integrate a css-in-js component (e.g. using the Styled Components library), as well as a Material-UI component, into React Proforma:
import styled from 'styled-components';
import { TextField } from '@material-ui/core';
import { Field } from 'react-proforma';
const StyledInput = styled.input`
color: blue;
font-size: 35px;
font-weight: 'bold';
padding: 8px;
margin-top: 5px;
`;
Field in the 'component' prop, and add whatever other props you would normally pass to that component:<Field
name="email"
component={TextField}
type="text"
required
label="Email"
margin="normal"
style={{ marginTop: '0', width: '100%' }}
/>
<Field
name="password"
component={StyledInput}
type="text"
required
placeholder="Password field"
/>
You can see a complete example here.
Proforma.config.customOnChangecustomOnChange object, along with your component state, can be used to fulfill special validation requirements.
customOnChange to restrict user input by only allowing a specific kind of input in a field.
TODO
Proforma is the core component of the React Proforma library. It is a React component that you return from your own component's render method (or returned from your functional component). It expects as a single child a function that will return your actual form markup. The child function can be declared in-line as an anonymous function, but I recommend referencing a named function instead, for organization, clarity, and efficiency.
The child function will be executed by Proforma with the entire ProformaBundle, so you can access it (or any part of it) inside the child function that you pass in.
For example:
NOTE: The child function does NOT HAVE PARENTHESES next to it. This is a function reference, not a function invocation.
import React from 'react';
import { Proforma } from 'react-proforma';
class MyForm extends React.Component {
renderForm(proformaBundle) {
/* extract any piece of the ProformaBundle */
const {
values,
touched,
errors,
handleSubmit
} = proformaBundle;
return (
<form onSubmit={handleSubmit}>
{/* form markup */}
</form>
);
}
render() {
return (
<Proforma
config={{...}}
handleSubmit={() => {...}}
>
{this.renderForm}
</Proforma>
);
}
}
Proforma.config
Proforma.config.initialValues: object
initialvalues: {
name: this.props.userName || '',
email: this.props.userEmail || '',
password: '',
newsletter: true
}
''.Proforma.config.validationObject: object
This is an optional object that allows you to define the validation you'd like to have performed on any of your form fields.
The keys must correspond with whichever form field names you wish to have validated, and the values are functions that accept the current 'values' object of your form as its sole argument. The return value from each function must either be an array of strings (containing the error messages to be placed in the 'errors' object for that field, even if there is only one error message), or null. For example:
validationObject: {
password: (values) => {
/*
Perform check on values.password.
Return array of error messages , or null.
*/
};
}
You can either do this manually, or make use of the fieldValidator helper function to streamline this process.
NOTE: I make the entire values object available to each validationObject property so that you can reference other field name values if you need to.
Proforma.config.customOnChangeObject: object
customOnChangeObject should be a name that corresponds with one of your form field names.customOnChangeObject should be a function that accepts two arguments:
Proforma are controlled, you will have to use setValues to update that particular form field yourself. For example:customOnChangeObject: {
name: (event, setValues) => {
const { value } = event.target;
/*
Any logic you want to perform on 'value'..
*/
const upperCaseValue = value.toUpperCase();
/* IMPORTANT (or UI won't update) */
setValues({ password: upperCaseValue });
};
}
Proforma.config.onValidateCallbacksObject: object
onValidateCallbacksObject should be a name that corresponds with one of your form field names.onValidateCallbacksObject should be a function that accepts no arguments and returns void. I.e. callback: () => void.Proforma.config.resetTouchedOnFocus: boolean
false when that field receives focus.false.Proforma.config.validateOnChange: boolean
true.Proforma.handleSubmit
event.preventDefault() for you, so don't worry about including that in your own handleSubmit.handleSubmit function inside a conditional that prevents a user from submitting the form many times with multiple clicks.
handleSubmit function makes use of the 'setSubmitting' function (see below) to set the 'isSubmitting' property to false, and for some reason you've kept the form component on the screen, the user WILL be able to submit the form again unless you make use of the 'submitCount' property (see below) to control a user's ability to re-submit your form.await in your function logic.handleSubmit function will be executed with the following arguments being made available to your function:
setSubmitting, setValues, setComplete, resetFields (this is handleReset in the ProformaBundle), and submitCount. In addition to these methods/properties, you can also find the 'event' object (React.FormEvent | React.SyntheticEvent) emitted by React when the form is submitted, should you need it. Note that I do the event.preventDefault() for you, so access the event object for anything other than that.<Proforma
config={{...}}
handleSubmit={async (values, {setSubmitting}) => {
/* Post values to server */
try {
const response = await axios.post(serverUrl, values);
if (response.data.message === 'success') {
/* redirect user somewhere */
} else {
console.log('Something went wrong!', response.data.error);
/* use setSubmitting to flip the 'isSubmitting' property inside ProformaBundle */
setSubmitting(false);
}
} catch (error) {
console.log('Something went wrong!', error);
/* use setSubmitting to flip the 'isSubmitting' property inside ProformaBundle */
setSubmitting(false);
}
}}
>
{this.renderForm}
</Proforma>
The Form component comes automatically wired up with Proforma's 'handleSubmit' function that you would normally have to wire up yourself by grabbing it from the PorformaBundle.
That is, this:
class MyForm extends React.Component {
renderForm(proformaBundle) {
return (
<form onSubmit={proformaBundle.handleSubmit}>
{/* ... */}
</form>
);
}
render() {
/* etc. etc. */
}
}
...is equal to this:
class MyForm extends React.Component {
renderForm(proformaBundle) {
return (
<Form>
{/* ... */}
</Form>
);
}
render() {
/* etc. etc. */
}
}
Simply import Form from React Proforma:
import { Form } from 'react-proforma';
form element returned from Form. See here for how to use this.Form will be forwarded onto the resulting React form element.This component will be your go-to for all input types that are not checkboxes, radio buttons, selects (dropdowns), or textareas. (I've separated those into their own components.) It comes automatically wired up as a controlled component.
The Field component must be passed a 'name' prop corresponding with one of the form field names in your 'initialValues' object in your Proforma.config. All other props will be forwarded to the resulting input element.
Simply import Field from React Proforma:
import { Field } from 'react-proforma';
Example:
<Field
name="password"
type="password"
className="form-field"
id="password-field"
style={{ color: 'blue', fontSize: '1.3rem' }}
/>
<Field
name="amount"
type="number"
className="form-field"
id="amount-field"
style={{ fontWeight: 'bold' }}
/>
input element to be.input element returned from Field. See here for how to use this.input or custom component.This component is for checkbox inputs. It comes automatically wired up as a controlled component.
The Checkbox component must be passed a 'name' prop corresponding with one of the form field names in your 'initialValues' object in your Proforma.config. All other props will be forwarded to the resulting input element.
NOTE: The 'initialValue' for a Checkbox input must be a BOOLEAN value, not a string.
Simply import Checkbox from React Proforma:
import { Checkbox } from 'react-proforma';
Example
<Checkbox name="newsletter" id="newsletter-checkbox" />
input element returned from Checkbox. See here for how to use this.input or custom component.This component is for radio button inputs. It comes automatically wired up as a controlled component.
The Radio component must be passed a 'name' prop corresponding with one of the form field names in your 'initialValues' object in your Proforma.config. All other props will be forwarded to the resulting input element.
Simply import Radio from React Proforma:
import { Radio } from 'react-proforma';
Example
<label htmlFor="gender-male">Male</label>
<Radio name="gender" value="male" id="gender-male" />
<label htmlFor="gender-female">Female</label>
<Radio name="gender" value="female" id="gender-male" />
<label htmlFor="gender-other">Other</label>
<Radio name="gender" value="other" id="gender-other" />
NOTE: Each radio button above has the same 'name' prop ("gender" in this case). This is required for the radio buttons to be considered part of the same radio grouping.
NOTE: Each radio button above has it's own 'value' prop. This make it different from other input types. The 'value' prop should be equal to the value that you'd like your form field name to have when that radio button is checked.
input element returned from Radio. See here for how to use this.input or custom component.This component is for select (dropdown) inputs. It comes automatically wired up as a controlled component.
The Select component must be passed a 'name' prop corresponding with one of the form field names in your 'initialValues' object in your Proforma.config. All other props will be forwarded to the resulting select element.
Simply import Select from React Proforma:
import { Select } from 'react-proforma';
Example
<Select name="salutation" id="salutation-select" className="form-field">
<option value="mister">Mr.</option>
<option value="missus">Mrs.</option>
<option value="miss">Ms.</option>
</Select>
select element returned from Select. See here for how to use this.select or custom component.This component is for textarea inputs. It comes automatically wired up as a controlled component.
The Textarea component must be passed a 'name' prop corresponding with one of the form field names in your 'initialValues' object in your Proforma.config. All other props will be forwarded to the resulting textarea element.
Simply import Textarea from React Proforma:
import { Textarea } from 'react-proforma';
Example
<Textarea
name="comment"
id="comment-input"
cols="50"
rows="10"
maxLength="120"
/>
textarea element returned from Textarea. See here for how to use this.textarea or custom component.This component is meant to be the control for your form submission. It comes automatically wired up to the ProformaBundle's handleSubmit method and 'isSubmitting' property.
As customization, it accepts 'textNotSubmitting' and 'textSubmitting' as optional props. See props section below for details.
Simply import Submit from React Proforma:
import { Submit } from 'react-proforma';
Example
<Submit textSubmitting="Processing form inputs..." />
button element returned from Submit. See here for how to use this.button or custom component.This component is meant to be the control for your form's reset functionality. It comes automatically wired up to the ProformaBundle's handleReset method.
As customization, it accepts 'text' as an optional prop. See props section below for details.
Simply import Reset from React Proforma:
import { Reset } from 'react-proforma';
Example
<Reset text="Click To Reset" />
button element returned from Reset. See here for how to use this.button or custom component.This component is designed for development purposes for you to display and track the current 'values', 'errors', and 'touched' objects for your form.
See what it looks like inside the 'Normal Usage' guide.
Import it,
import { Debug } from 'react-proforma';
and insert it anywhere within your markup:
<Debug />
ProformaBundle.values: object
ProformaBundle.touched: object
ProformaBundle.errors: object
null.ProformaBundle.isSubmitting: boolean
ProformaBundle.setSubmitting.ProformaBundle.isComplete: boolean
false, and is only turned true by you with a call to ProformaBundle.setComplete(true).ProformaBundle.submitCount: number
ProformaBundle.handleSubmit from your form.ProformaBundle.handleChange: function
ProformaBundle.handleFocus: function
ProformaBundle.handleBlur: function
ProformaBundle.handleSubmit: function
ProformaBundle.handleReset: function
null and false respectively.onClick property, or import the Reset component, which comes pre-wired up with 'ProformaBundle.handleReset'.ProformaBundle.setSubmitting: function
ProformaBundle.setComplete: function
fieldValidator chain from the validation function..end() to the end of your chain!import { fieldValidator } from 'react-proforma';
validationObject: {
userName: (values) => {
return fieldValidator(values.userName)
.required()
.min(6)
.max(20)
.end();
},
email: (values) => {
return fieldValidator(values.email)
.required()
.email()
.end();
}
}
fieldValidator(value):
required(msg?: string)
min(length: number, msg?: string)
max(length: number, msg?: string)
integer(msg?: string)
float(msg?: string)
email(msg?: string, rgx?: RegExp)
regex(rgx: RegExp, msg? string)
equals(comparedString: string, msg?: string)
custom(fn: () => string | undefined)
end()
.end() TO THE END OF ANY CHAIN of methods attached to fieldValidator in order for the chain to return the collection of error messages.import { fieldError } from 'react-proforma';
/* example error display component */
function FieldError(props) {
return <p style={{ color: 'red' }}>{props.error}</p>;
}
/* then insert the fieldError call somewhere in your mark-up */
<div className="field-row">
<label htmlFor="password-field">Enter password:</label>
<Field name="password" type="password" id="password-field"/>
</div>
{fieldError('password', FieldError)}
import { fieldValid } from 'react-proforma';
/* example valid-input display component */
function FieldValid(props) {
return <p style={{ color: 'green' }}>{props.error}</p>;
}
/* then insert the fieldValid call somewhere in your mark-up */
<div className="field-row">
<label htmlFor="password-field">Enter password:</label>
<Field name="password" type="password" id="password-field"/>
</div>
{fieldValid('password', FieldValid, 'Good stuff!')}
NOTE: 'fieldError' and 'fieldValid' can be used in conjunction with each other. Just place them one above the other, and either error messages or the valid input message will be displayed, depending on the current input in that field:
{fieldError('password', FieldError)}
{fieldValid('password', FieldValid, 'Good stuff!')}
Clone the Github repo:
git clone https://github.com/varunj166/react-proforma.git
Install dependencies
npm install
Run test suites
npm test
I've only looked at React Native in passing because web applications are my main focus (and are, in my opinion, the future, especially with the possibilities that PWA's make available to us), but if there is sufficient interest in this library, I could see about enlisting some help to make React Proforma compatible with React Native.
As I understand it, it shouldn't be that difficult, but I wouldn't want to introduce new functionality like that myself without the help of people with much stronger knowledge of React Native.
For now, React Proforma is strictly for React web forms.
I am, of course, aware of Formik, seeing as it's the most popular React form helper library out there. And I did work with Formik a bit, but there were design choices there that annoyed me, and for something as frequently needed as a form helper library, I didn't want to have to conform to designs that I didn't agree with.
That's what inspired me to build React Proforma. Everything about it is exactly how I would have wanted someone else's form helper library to be. And since that wasn't out there, I made it myself.
It works really well for me, and I hope it works well for you, too!
-vJ
FAQs
React Proforma helps you build simple to complex web forms with ease in React. -- Simplicity where you want it. Flexibility where you need it.
The npm package react-proforma receives a total of 10 weekly downloads. As such, react-proforma popularity was classified as not popular.
We found that react-proforma demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
OpenAI rotated macOS signing certificates after a malicious Axios package reached its CI pipeline in a broader software supply chain attack.

Security News
Open source is under attack because of how much value it creates. It has been the foundation of every major software innovation for the last three decades. This is not the time to walk away from it.

Security News
Socket CEO Feross Aboukhadijeh breaks down how North Korea hijacked Axios and what it means for the future of software supply chain security.