> ## Documentation Index
> Fetch the complete documentation index at: https://brushysuite.gfrancodev.com/llms.txt
> Use this file to discover all available pages before exploring further.

# React Hooks

# React Hooks

`@brushy/di` provides React hooks to facilitate dependency injection in functional components.

## useInject

The `useInject` hook allows injecting dependencies into React components.

### Import

```typescript theme={null}
import { useInject } from "@brushy/di";
```

### Basic Usage

```typescript theme={null}
import { createToken, useInject } from "@brushy/di";

const USER_SERVICE = createToken<UserService>("USER_SERVICE");

function UserList() {
  const userService = useInject(USER_SERVICE); // type inferred - no <UserService>

  // Use the service
  const [users, setUsers] = useState([]);

  useEffect(() => {
    userService.getUsers().then(setUsers);
  }, [userService]);

  return (
    <ul>
      {users.map(user => (
        <li key={user.id}>{user.name}</li>
      ))}
    </ul>
  );
}
```

### Options

```typescript theme={null}
// With options
const userService = useInject(USER_SERVICE, {
  // Disable promise caching
  cachePromises: false,

  // Use a specific scope
  scope: requestScope,
});
```

### Promise Caching

By default, `useInject` creates a proxy around the injected service that automatically caches promises returned by methods. This is useful to avoid multiple API calls during re-renders.

```typescript theme={null}
function UserProfile({ userId }) {
  const userService = useInject(USER_SERVICE);

  // This promise will be automatically cached
  const user = use(userService.getUserById(userId));

  return <div>{user.name}</div>;
}
```

## useInjectLazy

The `useInjectLazy` hook resolves a dependency **lazily** via a proxy - the service is created on first property or method access.

### Import

```typescript theme={null}
import { useInjectLazy } from "@brushy/di";
```

### Basic Usage

```typescript theme={null}
function ReportGenerator() {
  const reportService = useInjectLazy<ReportService>("REPORT_SERVICE");
  const [report, setReport] = useState(null);

  const generateReport = async () => {
    const data = await reportService.generate();
    setReport(data);
  };

  return (
    <div>
      <button onClick={generateReport}>Generate Report</button>
      {report && <ReportViewer data={report} />}
    </div>
  );
}
```

### Options

```typescript theme={null}
const reportService = useInjectLazy<ReportService>("REPORT_SERVICE", {
  scope: requestScope,
});
```

## Provider Integration

For the hooks to work, you need to wrap your application with `BrushyDIProvider`:

```tsx theme={null}
import { Container, BrushyDIProvider } from "@brushy/di";

// Create the container
const container = new Container({
  providers: [
    // ... provider configuration
  ],
});

// Application with provider
function App() {
  return (
    <BrushyDIProvider container={container}>
      <YourApp />
    </BrushyDIProvider>
  );
}
```

## Complete Example

```tsx theme={null}
import {
  Container,
  BrushyDIProvider,
  createToken,
  useInject,
  useInjectLazy,
} from "@brushy/di";
import { useState, useEffect } from "react";

// Tokens
const USER_SERVICE = createToken<UserService>("USER_SERVICE");
const ANALYTICS_SERVICE = createToken<AnalyticsService>("ANALYTICS_SERVICE");

// Services
class UserService {
  async getUsers() {
    return fetch("/api/users").then((r) => r.json());
  }
}

class AnalyticsService {
  trackEvent(name, data) {
    console.log(`Event: ${name}`, data);
  }
}

// Container
const container = new Container();
container.register(USER_SERVICE, { useClass: UserService });
container.register(ANALYTICS_SERVICE, { useClass: AnalyticsService });

// Component
function UserList() {
  const userService = useInject(USER_SERVICE);
  const analyticsService = useInjectLazy(ANALYTICS_SERVICE);
  const [users, setUsers] = useState([]);

  useEffect(() => {
    userService.getUsers().then(setUsers);
  }, [userService]);

  const trackClick = () => {
    analyticsService.trackEvent("user_list_clicked", { count: users.length });
  };

  return (
    <div onClick={trackClick}>
      <h1>Users</h1>
      <ul>
        {users.map((user) => (
          <li key={user.id}>{user.name}</li>
        ))}
      </ul>
    </div>
  );
}

// App
export default function App() {
  return (
    <BrushyDIProvider container={container}>
      <UserList />
    </BrushyDIProvider>
  );
}
```
