
Security News
/Research
Wallet-Draining npm Package Impersonates Nodemailer to Hijack Crypto Transactions
Malicious npm package impersonates Nodemailer and drains wallets by hijacking crypto transactions across multiple blockchains.
@resourge/react-form
Advanced tools
react-form is a simple and basic controlled hook form. Aiming to create forms with minimal effort.
@resourge/react-form
package provides a set of utilities for managing form state in React applications with built-in storage synchronization. It offers hooks and components designed to streamline form development, optimize rendering performance and seamlessly synchronize form data with storage solutions.
Form State Management
: Handle form inputs, validation, and submission with useForm
.Reactive Form State
: The form state is fully reactive, meaning any direct changes to the form trigger automatic updates across your components, ensuring your UI always reflects the current state.Automatic Storage Synchronization
: Sync form data with localStorage
or AsyncStorage
using useFormStorage
.Performance Optimization
: Efficient rendering with the Controller component.Context-based Architecture
: Use FormProvider
or Form
to pass form state to nested components.Customization and Flexibility
: Customize storage options, synchronization behavior, and form submission handling to suit your application's specific requirements.Developer-friendly API
: Simplified API to reduce boilerplate codeInstall using Yarn:
yarn add @resourge/react-form
or NPM:
npm install @resourge/react-form --save
or pnpm:
pnpm add @resourge/react-form
import { useForm } from "@resourge/react-form";
const MyForm = () => {
const { form, handleSubmit, field, hasError, getErrors } = useForm({
username: "",
password: "",
products: Array.from(
{
length: 100,
},
(_, i) => ({ productId: i + 1 })
),
getProducts() {
return this.products.map(({ productId }) => productId);
},
});
const productIds = form.getProducts();
const onSubmit = handleSubmit((data) => console.log("Form Submitted:", data));
return (
<form onSubmit={onSubmit}>
<input {...field("username")} placeholder="Username" />
{hasError("username") && <span>{getErrors("username")[0]}</span>}
<input {...field("password")} placeholder="Password" type="password" />
{hasError("password") && <span>{getErrors("password")[0]}</span>}
<button type="submit">Submit</button>
</form>
);
};
import { useFormSplitter, useForm } from "@resourge/react-form";
const PersonalDetails = () => {
const { form, field } = useFormSplitter("personalDetails");
return (
<>
<input {...field("firstName")} placeholder="First Name" />
<input {...field("lastName")} placeholder="Last Name" />
</>
);
};
const MyForm = () => {
const { form, handleSubmit, field, hasError, getErrors, context } = useForm({
personalDetails: {
username: "",
password: "",
},
});
const onSubmit = handleSubmit((data) => console.log("Form Submitted:", data));
return (
<Form context={context} onSubmit={onSubmit}>
<PersonalDetails />
<button type="submit">Submit</button>
</Form>
);
/*
or
return (
<FormProvider context={context}>
<PersonalDetails />
<button type="submit">Submit</button>
</FormProvider>
);
*/
};
import { useFormStorage } from "@resourge/react-form";
const MyPersistentForm = () => {
const { form, handleSubmit, restoreFromStorage } = useFormStorage(
{ username: "", password: "" },
{
storage: localStorage,
uniqueId: "myForm",
autoSyncWithStorage: true,
onLoading: (isLoading) => {
// Handle loading state
},
onStorageError: (error) => {
// Handle storage error
},
shouldClearAfterSubmit: true,
version: "1.0.0",
}
);
const onSubmit = handleSubmit((data) => console.log("Form Submitted:", data));
return (
<Form onSubmit={onSubmit}>
<input {...field("username")} placeholder="Username" />
{hasError("username") && <span>{getErrors("username")[0]}</span>}
<input {...field("password")} placeholder="Password" type="password" />
{hasError("password") && <span>{getErrors("password")[0]}</span>}
<button type="submit">Submit</button>
</Form>
);
};
Manages form state and validation.
initialState
: Initial form value (object, function returning an object, or class instance).options
(optional):
onChange
: Triggered on form state change, receiving the current stateonSubmit
: Triggered on successful form submission, receiving form data.validate
: Custom validation function, takes form data and changed keys, returns error messages or throws errors.watch
: Triggered when a specified key changes. Useful for updating dependent data, especially in asynchronous scenarios (e.g., fetching async data).validationType
: Controls when validation errors are shown:
onSubmit
: Appear only after submission. Newly added fields only display errors after submitting.onTouch
: Errors show after field touch.always
: Show immediatelychangeValue(key: string, value: any): void
: Changes the value of a specific form field.
changeValue("name", "John");
context
: Provides a context object for integration with FormProvider
/Controller
/Form
.errors
: Contains error messages for each form field.
errors["email"]?.errors && (
<span className="error">{errors["email"]?.errors}</span>
);
field(key: string, options?: FieldOptions): FieldForm
: Connects form elements to specific fields.
blur
: For changes only in bluronChange
: Custom changes on value change.readOnly
: Readonly onlydebounce
: Built-in debouncing (ms)<input {...field("name")} />
form
: Reactive form state.
const emailValue = form.email;
form.email = "newEmail@email.email";
getErrors(key: string, options?: GetErrorsOptions): GetErrors
: Retrieves error messages for a form field.
includeChildsIntoArray
: Include all errors from child's.unique
: By default it will only return unique errors, filtering repeating.const passwordErrors = getErrors("password");
getValue(key: string): any
: Fetches the value of a form field.
const usernameValue = getValue("username");
handleSubmit(onValid: SubmitHandler, validateErrors?: ValidateSubmissionErrors): (event?: FormEvent<HTMLFormElement> | react.MouseEvent) => Promise<K | undefined>
: Handles form submission, processing valid form data and managing invalid data based on custom logic.
const submitHandler = handleSubmit(
(form) => {
// Submit form data to the server
},
(errors) => {
// Control which validation errors are acceptable for submission.
// Allows dynamic error handling based on submission context.
return errors;
}
);
hasError(key: string, options?: ErrorsOptions): boolean
: Checks if a form field has errors.
includeChildsIntoArray
: Include all errors from child's.const hasUsernameError = hasError("username");
hasTouch(key: string): boolean
: Checks if a form field was touched.
const hasUsernameTouch = hasTouch("username");
isTouched
: Indicates if any field has been touched.isValid
: Indicates if the form is valid.reset(newForm?: Partial<Record<string, any>>, resetOptions?: ResetOptions): Promise<void>
: Resets the form state.
clearTouched
: Clear's touches on reset (default).reset({});
resetTouch(): void
: Clears touch states for all form fields.
resetTouch();
setError(errors: Array<{ errors: string[], path: string }>): void
: Sets custom errors for specific form fields.
setError([{ path: "email", errors: ["Invalid email address"] }]);
updateController(key: string): void
: Forces an update of the Controller
for a form field.
updateController("email");
watch<V>(key: string, method: WatchMethod): V
: (REMOVED) Changed to useForm
options.Breaks up large forms into smaller parts.
formFieldKey
(optional): Key from the form
state for the splitter form. It's required unless useFormSplitter
is used inside a Controller
.formFieldKey
A specialized version of useForm that persists form state to local storage or session storage.
defaultValue
: Initial value or a function returning the initial value of the form.options
: Configuration options for form storage, extending those from useForm
hook.
storage
: Storage mechanism (e.g., localStorage
) for saving form data.uniqueId
: A unique identifier for the form data in storage.autoSyncWithStorage
(optional, default: true
): Whether to sync form data with storage automatically.onLoading
(optional): Callback for handling loading state when reading from storage.onStorageError
(optional): Callback for handling errors during storage operations.shouldClearAfterSubmit
(optional, default: true
): Whether to clear form data from storage after submission.version
(optional, default: '1.0.0'
): Version string to track changes in form data and clear storage when needed.restoreFromStorage
: Synchronizes the form data with the data stored in the storage mechanism.Class instances work with useFormStorage
when using the PreserveClass
or registerClass
functions. These functions preserve the class prototypes, ensuring that class instances interact correctly with the form storage mechanism. This is useful for forms with complex data structures or when data is encapsulated within classes.
PreserveClass
is a utility function for registering a class with useFormStorage
to handle serialization. It ensures that instances of the class are correctly serialized and deserialized when interacting with the storage mechanism.
import { PreserveClass } from "useFormStorage";
// Define form data structure
@PreserveClass
class UserData {
name: string;
email: string;
constructor() {
this.name = "";
this.email = "";
}
}
registerClass
is a utility function that allows you to manually register a class for serialization, providing an alternative to using decorators.
import { registerClass } from "useFormStorage";
// Define form data structure
class UserData {
name: string;
email: string;
constructor() {
this.name = "";
this.email = "";
}
}
// Register class for serialization
registerClass(UserData);
Provides form context to nested components.
import { FormProvider, useForm } from "@resourge/react-form";
const MyFormComponent = () => {
const { context } = useForm<MyFormData>(); // Replace MyFormData with your form data type
// Access form data, state, and methods from context
return (
<FormProvider context={context}>{/* Your form components */}</FormProvider>
);
};
Wraps a form and provides context to nested components.
import { FormProvider, useForm } from "@resourge/react-form";
const MyFormComponent = () => {
const { context } = useForm<MyFormData>(); // Replace MyFormData with your form data type
// Access form data, state, and methods from context
return (
<Form context={context} onSubmit={(form) => {
...
}}>{/* Your form components */}</Form>
);
};
Hook to access the state of a FormProvider
or Form
.
import { useFormContext } from "@resourge/react-form";
const context = useFormContext<MyFormData>();
Optimizes form field rendering for large forms.
import { Controller, useForm } from "@resourge/react-form";
const MyFormComponent = () => {
const { context } = useForm<MyFormData>(); // Replace MyFormData with your form data type
// Access form data, state, and methods from context
return (
<FormProvider context={context}>
<Controller name="fieldName" context={context}>
{/* Your form field components */}
</Controller>
</FormProvider>
);
};
For comprehensive documentation and usage examples, visit the react-form documentation.
Contributions to @resourge/react-form
are welcome! To contribute, please follow the contributing guidelines.
@resourge/react-form
is licensed under the MIT License.
For questions or support, please contact the maintainers:
FAQs
react-form is a simple and basic controlled hook form. Aiming to create forms with minimal effort.
The npm package @resourge/react-form receives a total of 26 weekly downloads. As such, @resourge/react-form popularity was classified as not popular.
We found that @resourge/react-form demonstrated a healthy version release cadence and project activity because the last version was released less than 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
/Research
Malicious npm package impersonates Nodemailer and drains wallets by hijacking crypto transactions across multiple blockchains.
Security News
This episode explores the hard problem of reachability analysis, from static analysis limits to handling dynamic languages and massive dependency trees.
Security News
/Research
Malicious Nx npm versions stole secrets and wallet info using AI CLI tools; Socket’s AI scanner detected the supply chain attack and flagged the malware.