<ReactFormProvider> - Global Configuration Provider
The ReactFormProvider component allows you to configure global options for all <ReactForm> components within your application. It uses React Context to provide these options to all child components.
Wrap your application (or a section of it) with <ReactFormProvider> to set default behavior that applies to all forms unless overridden at the form level.
import { ReactFormProvider } from "@7span/react-form";
function App() {
return (
<ReactFormProvider
isNewItemCheck={({ itemId }) => itemId === "create"}
errorAdapter={(error) => ({
name: error.name || "Unknown Error",
message: error.message || "An error occurred",
fieldErrors: error.errors || {},
})}
schemaToFields={schemaToFields}
validateSchema={validateSchema}
>
{/* Your app components */}
</ReactFormProvider>
);
}Props
All props are optional and will fall back to default values if not provided.
isNewItemCheck
- Type:
Function - Optional
- Default:
({ itemId }) => itemId === "create"
Function that determines whether a form should operate in create mode or edit mode. Read more
errorAdapter
- Type:
Function - Optional
Function that transforms API error responses into a standardized format. Read more
isArchivedItemCheck
- Type:
Function - Optional
- Default:
(response) => response?.isArchived === true
Function that determines if an item is archived. Called after read, create, update, archive, or unarchive operations.
schemaToFields
- Type:
Function - Default:
schemaToFields: (schema) => {
console.warn("schemaToFields is not provided");
return [];
};Custom function to extract field definitions from your validation schema. See Options for detailed examples.
validateSchema
- Type:
Function - Default:
validateSchema: (schema, values) => {
console.warn("validateSchema is not provided");
return {
success: false,
errors: {},
};
};Custom validation function that accepts your schema and form values, and returns a validation result. See Options for detailed examples.
componentPrefix
- Type:
String - Optional
- Default:
""
Component prefix. Not used in React (kept for consistency with React version).
Usage
Basic Setup
import { ReactFormProvider } from "@7span/react-form";
function Root() {
return (
<ReactFormProvider>
<App />
</ReactFormProvider>
);
}With Validation (Zod)
import { ReactFormProvider } from "@7span/react-form";
// Schema to fields converter
const schemaToFields = (schema) => {
return Object.keys(schema.shape).map((key) => {
const zodField = schema.shape[key];
/*
- "defaultValue" & "description" key can be vary or not found
with different zod version (current - v4)
- check it with console.log("zodField:", zodField);
- Need to map the keys accordingly
*/
const defaultValue = zodField.def.defaultValue;
const label = zodField.description;
return {
name: key,
label: label || key.charAt(0).toUpperCase() + key.slice(1),
value: defaultValue,
};
});
};
// Validation function
const validateSchema = async (schema, values) => {
const result = schema.safeParse(values);
if (result.success) {
return { success: true, errors: {} };
}
const fieldErrors = result.error.issues.reduce((acc, issue) => {
const field = issue.path[0];
if (!field) return acc;
acc[field] = { message: issue.message };
return acc;
}, {});
return { success: false, errors: fieldErrors };
};
function Root() {
return (
<ReactFormProvider
schemaToFields={schemaToFields}
validateSchema={validateSchema}
>
<App />
</ReactFormProvider>
);
}With Validation (Yup)
import { ReactFormProvider } from "@7span/react-form";
// Schema to fields converter
const schemaToFields = (schema) => {
return Object.keys(schema.fields).map((key) => {
const yupField = schema.fields[key];
/*
- ".spec.default" & ".spec.label" key can be vary or not found
with different yup version (current - 1.7.1)
- check it with console.log("yupField:", yupField);
- Need to map the keys accordingly
*/
const label = yupField.spec.label;
const defaultValue = yupField.spec.default;
return {
name: key,
label: label || key.charAt(0).toUpperCase() + key.slice(1),
value: defaultValue,
};
});
};
// Validation function
const validateSchema = async (schema, values) => {
try {
await schema.validate(values, { abortEarly: false });
return { success: true, errors: {} };
} catch (error) {
const fieldErrors = {};
if (error.inner) {
error.inner.forEach((err) => {
if (err.path) {
fieldErrors[err.path] = { message: err.message };
}
});
}
return { success: false, errors: fieldErrors };
}
};
function Root() {
return (
<ReactFormProvider
schemaToFields={schemaToFields}
validateSchema={validateSchema}
>
<App />
</ReactFormProvider>
);
}With Multiple Options
<ReactFormProvider
isNewItemCheck={({ itemId }) => itemId === "new"}
isArchivedItemCheck={(response) => response?.archived === true}
errorAdapter={(error) => ({
name: error.name || "RequestError",
message: error.message || "Request failed",
fieldErrors: error.errors || {},
})}
schemaToFields={schemaToFields}
validateSchema={validateSchema}
>
<App />
</ReactFormProvider>Overriding Provider Options
Options set in <ReactFormProvider> can be overridden at the form level by passing the same props directly to <ReactForm>:
<ReactFormProvider
isNewItemCheck={({ itemId }) => itemId === "create"}
validateSchema={globalValidateSchema}
>
{/* This form uses provider defaults */}
<ReactForm schema={schema} create={create} />
{/* This form overrides the provider */}
<ReactForm
schema={schema}
create={create}
isNewItemCheck={({ itemId }) => itemId === "new"}
validateSchema={localValidateSchema}
/>
</ReactFormProvider>When to Use
Use <ReactFormProvider> when you want to:
- Share validation logic across multiple forms
- Standardize error handling across your application
- Configure default behavior for all forms
- Avoid repetition of common configuration
If you only have one form or need form-specific configuration, you can pass options directly to <ReactForm> instead.