npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@effijs/form-react

v2.0.10

Published

An efficient, modern way to organize the business logic of an application(@effijs/form-react)

Downloads

149

Readme

Introduction

@effijs/form-react is a powerful React form library built on top of the Store.Form module from @effijs/common. This library provides a comprehensive solution for handling form state, validation, and complex nested data structures in React applications.

It offers a declarative API to build forms with minimal boilerplate code. It efficiently manages form state, handles field dependencies, and provides utilities for data validation and manipulation.

The library adopts a component-based approach where forms are composed of various specialized components, each serving a specific purpose in the form structure hierarchy.

Core Components

Form

The main container component that establishes the form context and manages the form state.

Props:

  • Store.Form: The form store instance from @effijs/common
  • children: React elements representing form content

Usage:

import {useMemo} from 'react';
import {Form} from '@effijs/form-react';
import {Store, Validator} from '@effijs/common';

@Validator.Decorators.Options({
    skipMissingProperties: true,
})
class FormDataValidator {
    @Validator.Decorators.Property()
    @Validator.Decorators.Validator(
        (value) => value.length >= 2,
        "Title must be at least 2 characters long",
    )
    title?: string;
    
    ...
}

const MyForm = ({initial}: {initial: any}) => {
    const formStore = useMemo(() => new Store.Form(initial, FormDataValidator), []);

    const handleSubmit = () => {
        const {validated, error} = store.validate();
        if (error) {
            return error
        }
        console.log(validated);
    };

    return (
        <>
            <Form store={formStore}>
                {/* Form fields go here */}
            </Form>
            <button onClick={handleSubmit}>Submit</button>
        </>
    );
};

Form.Item

A component that connects a form field to the form store.

Props:

  • name: Field name (path) in the form state
  • initial: Optional initial value for the field
  • children: The form field component to render
  • deps: Optional dependencies that should trigger re-render and passes to component

Usage:

<Form.Item name="confirm-password" initial="" deps={['password']}>
    <input type="text"/>
</Form.Item>

Form.Obj

A component for handling nested object structures in forms.

Props:

  • name: Object name (path) in the form state
  • children: React nodes representing nested form fields

Usage:

<Form.Obj name="address">
    <Form.Item name="street">
        <input type="text"/>
    </Form.Item>
    <Form.Item name="city">
        <input type="text"/>
    </Form.Item>
</Form.Obj>

Form.List

A component for handling array structures in forms.

Props:

  • name: Array name (path) in the form state
  • children: Template for array items
  • keyExtractor: Optional function to extract unique keys for list items

Usage:

<Form.List name="contacts">
    <AddDeleteActions>
        <Form.Item name="name">
            <input type="text"/>
        </Form.Item>
        <Form.Item name="phone">
            <input type="text"/>
        </Form.Item>
    </AddDeleteActions>
</Form.List>

function AddDeleteActions({
    onAdd, onRemove, children, isLast, isFirst,
}: {
    onAdd?: () => void;
    onRemove?: () => void;
    children?: React.ReactNode;
    isLast?: boolean;
    isFirst?: boolean;
    }) {
    
    return (
        <>
            {children}
            {/* Actions go here */}
        </>
    );
}

Form.Data

A component for accessing form data and errors within the component tree.

Props:

  • children: React element that can access form data

Usage:

<Form.Data>
    {({data, error}) => (
        <div className={error.username ? 'error': ''}>
            Current username: {data.username}
        </div>
    )}
</Form.Data>

Form.Proxy

A component for sharing form context with components outside the form tree.

Props:

  • form: Form context object
  • children: React elements to receive the form context

Usage:

const {store} = Form.useForm();

// Later in component tree, possibly in a different component
<Form.Proxy form={{store}}>
    <SomeComponent/>
</Form.Proxy>

Form.CleanOnDestroy

A utility component that cleans up specified form fields when unmounted.

Props:

  • keys: Array of field names to clean up on component unmount

Usage:

<Form.CleanOnDestroy keys={['temporaryField']}>
    <TemporaryFormSection/>
</Form.CleanOnDestroy>

Form.DestroyWhen

A component that conditionally destroys form data based on a condition.

Props:

  • name: Field name in the form state
  • initial: Optional initial value
  • children: React element
  • condition: Function that determines when to destroy the field value
  • deps: Optional dependencies that should trigger condition evaluation

Usage:

<Form.DestroyWhen
    name="additionalInfo"
    condition={(value, deps) => deps.includeAdditional === false}
    deps={{includeAdditional: 'includeAdditional'}}
>
    <textarea/>
</Form.DestroyWhen>

Hooks

useForm

Hook for accessing a form store instance.

Returns:

  • store: Form store instance

Usage:

const MyForm = () => {
    const {store} = Form.useForm();

    // Use store methods like getValues(), setValues(), etc.
    return <Form store={store}>{/* Form fields */}</Form>;
};

useFormStore

Hook for accessing the current form store context.

Returns:

  • Form store context

Usage:

const FormField = () => {
    const formStore = useFormStore();

    // Access form state, methods, etc.
    return <div>{/* Field implementation */}</div>;
};

Advanced Examples

Complex Nested Form

import {Form} from '@effijs/form-react';
import {Store} from '@effijs/common';

const ComplexForm = ({initial}) => {
    const formStore = useMemo(() => new Store.Form(initial, FormDataValidator), []);

    const handleSubmit = () => {
        const {validated, error} = store.validate();
        if (error) {
            return error
        }
        console.log(validated);
    };

    return (
        <>
            <Form store={formStore}>
                <div>
                    <h2>Personal Information</h2>
                    <Form.Item name="firstName" initial="">
                        <input placeholder="First Name"/>
                    </Form.Item>
                    <Form.Item name="lastName" initial="">
                        <input placeholder="Last Name"/>
                    </Form.Item>

                    <h2>Address</h2>
                    <Form.Obj name="address">
                        <Form.Item name="street" initial="">
                            <input placeholder="Street"/>
                        </Form.Item>
                        <Form.Item name="city" initial="">
                            <input placeholder="City"/>
                        </Form.Item>
                        <Form.Item name="zipCode" initial="">
                            <input placeholder="Zip Code"/>
                        </Form.Item>
                    </Form.Obj>

                    <h2>Contacts</h2>
                    <Form.List name="contacts">
                        <FormListActions>
                            <div style={{display: 'flex', gap: '10px', marginBottom: '10px'}}>
                                <Form.Item name="type" initial="email">
                                    <select>
                                        <option value="email">Email</option>
                                        <option value="phone">Phone</option>
                                    </select>
                                </Form.Item>
                                <Form.Item name="value" initial="">
                                    <input placeholder="Contact Value"/>
                                </Form.Item>
                            </div>
                        </FormListActions>
                    </Form.List>
                </div>
            </Form>
            <button onClick={handleSubmit}>Submit</button>
        </>
    );
};

Summary

@effijs/form-react provides a flexible and powerful solution for building complex forms in React applications. Its component-based approach allows for intuitive form structure definition while the underlying Store.Form from @effijs/common efficiently manages the form state and validation.

Key features:

  • Declarative API with reusable components
  • Support for deeply nested objects and arrays
  • Conditional form fields
  • Form state access via hooks
  • Clean-up utilities to prevent stale data
  • Dependencies tracking for dynamic form behavior

By combining these building blocks, developers can create sophisticated forms with complex data structures while maintaining clean and maintainable code.