You're Invited:Meet the Socket Team at BlackHat and DEF CON in Las Vegas, Aug 4-6.RSVP
Socket
Book a DemoInstallSign in
Socket

f-box-react

Package Overview
Dependencies
Maintainers
1
Versions
27
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

f-box-react

React hooks and utilities for working with f-box-core.

0.2.11
latest
Source
npmnpm
Version published
Weekly downloads
89
147.22%
Maintainers
1
Weekly downloads
 
Created
Source

F-Box React

npm version License: MIT

F-Box React is a TypeScript library that provides React hooks and utilities to seamlessly integrate F-Box Core functional programming patterns into React applications. It focuses on reactive state management using RBox (Reactive Box) and functional programming abstractions.

Features

  • Reactive State Management: Reactive state management using RBox
  • Functional Programming: Support for functional operators like ["<$>"], ["<*>"], [">>="]
  • Type Safety: Complete type safety through TypeScript generics
  • SSR Support: Full server-side rendering compatibility
  • Lightweight: Minimal dependencies with lightweight design

Installation

npm install f-box-react

Required dependencies (peerDependencies):

npm install f-box-core react react-dom

API Reference

Main Hooks

useBox

A hook for managing static values with Box abstraction

import { useBox } from "f-box-react";

function App() {
  const [value, valueBox] = useBox(10);
  const [squared] = useBox(() => valueBox["<$>"]((x) => x * x));

  return (
    <div>
      <p>Original Value: {value}</p>
      <p>Squared Value: {squared}</p>
    </div>
  );
}

useRBox

Core reactive state management hook using RBox. This is the foundation hook that all other hooks are built upon.

Function Signatures

// Pattern 1: Pass an existing RBox
function useRBox<T>(source: RBox<T>): [T, RBox<T>];

// Pattern 2: Create a new RBox from a value or factory function
function useRBox<T>(
  source: T | (() => T | RBox<T>),
  deps?: React.DependencyList
): [T, RBox<T>];

Usage Patterns

Pattern 1: Local State (Most Common)

import { useRBox, set } from "f-box-react";

function Counter() {
  // Creates a new RBox with initial value 0
  const [count, countBox] = useRBox(0);
  const setCount = set(countBox);

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
}

Pattern 2: Global State

import { RBox } from "f-box-core";
import { useRBox, set } from "f-box-react";

// Create global RBox outside component
const globalCountBox = RBox.pack(0);

function Counter() {
  // Use existing RBox - shares state globally
  const [count] = useRBox(globalCountBox);
  const setCount = set(globalCountBox);

  return (
    <div>
      <p>Global Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
}

function ResetButton() {
  // Another component using the same global state
  const setCount = set(globalCountBox);
  return <button onClick={() => setCount(0)}>Reset</button>;
}

Pattern 3: Factory Function

function TimestampComponent() {
  // Factory function runs only on mount (empty deps array)
  const [timestamp] = useRBox(() => Date.now(), []);

  return <div>Created at: {new Date(timestamp).toLocaleString()}</div>;
}

Pattern 4: Factory Function with Dependencies

function UserProfile({ userId }: { userId: number }) {
  // Factory function re-runs when userId changes
  const [userBox] = useRBox(() => {
    // Create initial state based on userId
    return { id: userId, name: `User ${userId}`, loading: true };
  }, [userId]);

  // userBox is recreated whenever userId changes
  return <div>User ID: {userBox.id}</div>;
}

Pattern 5: Factory Function Returning RBox

function ComplexState({ config }: { config: Config }) {
  // Factory can return either a value or an existing RBox
  const [state, stateBox] = useRBox(() => {
    if (config.useGlobalState) {
      return getGlobalStateBox(); // Returns existing RBox
    } else {
      return createInitialState(config); // Returns plain value
    }
  }, [config]);

  return <div>State: {JSON.stringify(state)}</div>;
}

Pattern 6: Computed State

function Calculator() {
  const [a, aBox] = useRBox(5);
  const [b, bBox] = useRBox(3);
  
  // Derive computed state from other RBoxes
  const [sum] = useRBox(() => {
    return RBox.pack(0)["<$>"](() => a + b);
  }, [a, b]);

  return <div>Sum: {sum}</div>;
}

Key Points

  • Return Value: Always returns [currentValue, rbox] tuple
  • Reactivity: Components automatically re-render when RBox value changes
  • Global State: Pass existing RBox to share state across components
  • Local State: Pass initial value to create component-local state
  • Factory Functions: Use for computed initial values or conditional RBox creation
  • Dependencies: Factory functions re-run when dependencies change
  • SSR Safe: Uses useSyncExternalStore for server-side rendering compatibility

useRBoxForm

Form state management hook with validation

import { useRBoxForm } from "f-box-react";

type Form = {
  name: string;
  email: string;
};

const initialValues: Form = { name: "", email: "" };

const validate = (form: Form) => ({
  name: [() => form.name.length >= 2],
  email: [() => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(form.email)],
});

function ContactForm() {
  const { form, handleChange, handleValidatedSubmit, renderErrorMessages } =
    useRBoxForm<Form>(initialValues, validate);

  const handleSubmit = handleValidatedSubmit((form) => {
    console.log("Form submitted:", form);
  });

  return (
    <form onSubmit={handleSubmit}>
      <label>
        Name:
        <input
          value={form.name}
          onChange={(e) => handleChange("name", e.target.value)}
        />
        {renderErrorMessages("name", ["Name must be at least 2 characters"])}
      </label>
      <label>
        Email:
        <input
          value={form.email}
          onChange={(e) => handleChange("email", e.target.value)}
        />
        {renderErrorMessages("email", ["Please enter a valid email address"])}
      </label>
      <button type="submit">Submit</button>
    </form>
  );
}

useRBoxResource

Asynchronous resource management hook with caching capabilities

import { useRBoxResource } from "f-box-react";
import { Task } from "f-box-core";

type User = { id: number; name: string; email: string };

function UserProfile({ userId }: { userId: number }) {
  const [result, isLoading, controller] = useRBoxResource(
    ({ id }: { id: number }) =>
      Task.from(async () => {
        const response = await fetch(`/api/users/${id}`);
        if (!response.ok) throw new Error('Failed to fetch user');
        return response.json() as User;
      }),
    { id: userId }
  );

  const content = result.match(
    (error) => <div>Error: {error.message}</div>,
    (user) => (
      <div>
        <h2>{user.name}</h2>
        <p>Email: {user.email}</p>
      </div>
    )
  );

  return (
    <div>
      {isLoading && <div>Loading...</div>}
      {content}
      <button onClick={controller.refetch}>Refresh</button>
    </div>
  );
}

useRBoxTransaction

Asynchronous state transition management hook

import { useRBoxTransaction } from "f-box-react";

function AsyncAction() {
  const [isPending, startTransaction] = useRBoxTransaction();

  const performAction = async () => {
    await startTransaction(async () => {
      console.log("Processing started");
      await new Promise((resolve) => setTimeout(resolve, 2000));
      console.log("Processing completed");
    });
  };

  return (
    <div>
      <p>{isPending ? "Processing..." : "Idle"}</p>
      <button onClick={performAction} disabled={isPending}>
        Execute Async Process
      </button>
    </div>
  );
}

Contributing

Pull requests and issue reports are welcome.

Development Environment Setup

# Clone the repository
git clone https://github.com/YourUsername/f-box-react.git
cd f-box-react

# Install dependencies
npm install

# Start development server
npm run dev

Development Commands

npm run dev      # Start Vite development server
npm run build    # Build the library
npm run lint     # TypeScript type checking
npm test         # Run tests with Vitest in watch mode
npm run coverage # Run tests with coverage report

Testing

  • Framework: Vitest + React Testing Library
  • Environment: jsdom
  • Run specific tests: npm test -- useRBox.test.ts

Support

License

MIT License - See the LICENSE file for details.

Keywords

typescript

FAQs

Package last updated on 20 Jun 2025

Did you know?

Socket

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.

Install

Related posts