React Validate Framework
React Validate Framework is a lightweight form validation utility for React applications. It enables declaration of validation schemas and custom methods, supporting both synchronous and asynchronous validation. The library utilizes the decorator pattern via `@formConnect` to integrate validation logic into class components. It also provides a set of pre-built form components (Checkbox, Radio, Select, Text, Textarea, Message) that connect to the validation system, as well as an API for manual integration with unencapsulated components. The current stable version is 0.15.6, but the package has not been updated in approximately eight years, making it incompatible with modern React versions (17+) and development practices. Its core functionality relies on older React APIs and Babel features.
Common errors
-
TypeError: Cannot read properties of undefined (reading 'formControl')
cause The `@formConnect` decorator either failed to apply, or the component is not receiving `formControl` via props as expected. This can happen if Babel is not configured correctly for decorators, or if the component is mounted outside the context of `formConnect`.fixVerify that your Babel configuration correctly includes `@babel/plugin-proposal-decorators` (with `legacy: true`) and that the component decorated with `@formConnect` is part of a rendered tree. -
Support for the experimental syntax 'decorators-legacy' isn't currently enabled
cause Your Babel configuration does not include the necessary plugin to parse legacy decorator syntax, or it's misconfigured.fixInstall `@babel/plugin-proposal-decorators` and add it to your Babel configuration (e.g., `.babelrc`) with `{ "legacy": true }`. Ensure the plugin order is correct if you have other plugins like `class-properties`. -
Error: ReactDOM.render is no longer supported in React 18. Use createRoot instead.
cause Attempting to use this library with React 18+. The library's core design and peer dependencies are tied to React 15/16, which used `ReactDOM.render` for root creation.fixDowngrade your React and React DOM versions to 16.x (e.g., `npm install react@16 react-dom@16 prop-types@15`). Or, if you need React 18, replace this library with a modern alternative. -
ReferenceError: regeneratorRuntime is not defined
cause Asynchronous validation methods (`async/await`) are used, but your JavaScript environment or Babel setup does not include the `regenerator-runtime` polyfill.fixInstall `regenerator-runtime` (`npm install regenerator-runtime`) and import it at the entry point of your application (`import 'regenerator-runtime/runtime';`) or configure Babel to include the necessary polyfills via `@babel/preset-env`.
Warnings
- breaking This package is incompatible with React versions 17 and 18+. It explicitly lists peer dependencies for React 15.x || 16.x, and relies on older React internal mechanisms and deprecated `ReactDOM.render` API patterns which were replaced by `createRoot` in React 18.
- gotcha The project is abandoned. The last release was approximately 8 years ago, and there are no signs of ongoing maintenance, bug fixes, security patches, or compatibility updates for newer React versions or JavaScript features.
- breaking Version 0.13.0 introduced a breaking change by altering the internal `contextTypes` mechanism to `formControl`. This impacts how form context is accessed and managed within components, requiring updates to any custom components or higher-order components that directly interacted with the form's context.
- gotcha The `@formConnect` decorator syntax requires explicit Babel configuration with `@babel/plugin-proposal-decorators` (and often `{ "legacy": true }`). This is not enabled by default in Create React App or other modern build setups without custom tooling like `react-app-rewired`.
- deprecated The use of `contextTypes` for passing information down the component tree is a legacy React API that has been largely deprecated in favor of the Context API (`React.createContext`). While this library abstracts it, its underlying implementation uses outdated patterns.
Install
-
npm install react-validate-framework -
yarn add react-validate-framework -
pnpm add react-validate-framework
Imports
- formConnect
const formConnect = require('react-validate-framework');import formConnect from 'react-validate-framework';
- Text
import Text from 'react-validate-framework';
import { Text } from 'react-validate-framework'; - Message
import * as Messages from 'react-validate-framework';
import { Message } from 'react-validate-framework';
Quickstart
import React from 'react';
import PropTypes from 'prop-types';
import formConnect, { Text, Message } from 'react-validate-framework';
// Note: This project is abandoned and requires React 15/16 and Babel decorator setup.
// npm install react-validate-framework react@16 react-dom@16 prop-types --save
// npm install @babel/plugin-proposal-decorators --save-dev
// Ensure your Babel config (e.g., .babelrc) includes:
// {"plugins": [["@babel/plugin-proposal-decorators", { "legacy": true }]]}
const schemas = {
email: {
rules: 'required | isEmail | maxLength(32)',
messages: 'Can not be empty! | Please enter a valid email address. | Can not exceed {{param}} characters.',
},
password: {
rules: 'required | minLength(6)',
messages: 'Password is required! | Must be at least {{param}} characters.',
},
};
const methods = {
// Custom methods for rules can be defined here if needed, e.g., async validation.
// async validateFromServer(field, param) { /* ... */ }
};
@formConnect(schemas, methods)
export default class BasicForm extends React.Component {
static propTypes = {
formControl: PropTypes.object,
};
constructor(props) {
super(props);
props.formControl.init({
email: '',
password: '',
}, {
static: 'form-control',
success: 'valid-success',
error: 'valid-error',
});
}
handleSubmit = async () => {
const { formControl } = this.props;
if (await formControl.validate()) {
console.log('Form is valid. Submitting values:', formControl.formValues);
// Implement your form submission logic here
} else {
console.log('Form has validation errors.');
}
};
render() {
return (
<div className="form-group">
<label htmlFor="email">Email:</label>
<Text
name="email"
id="email"
placeholder="Please input your email"
delay={100} // Debounce for asynchronous validation
/>
<Message className="valid-error-message" name="email" />
<label htmlFor="password">Password:</label>
<Text
name="password"
id="password"
type="password"
placeholder="Please input your password"
/>
<Message className="valid-error-message" name="password" />
<button onClick={this.handleSubmit}>Submit</button>
</div>
);
}
}