npm package: @mirawision/react-wings
Description: React hooks for the Wings state management library, providing seamless integration between React components and Wings state management.
Author: Yelysei Lukin
Latest version: 1.0.0

# @mirawision/react-wings

React hooks for the Wings state management library, providing seamless integration between React components and Wings state management. This library offers a simple and powerful way to use Wings state management in React applications.

## Features

- **React Hooks Integration**: Custom hooks for Wings state management
- **Type Safety**: Full TypeScript support with generics
- **Automatic Cleanup**: Proper subscription management and cleanup
- **Performance Optimized**: Efficient re-rendering with state changes
- **Seamless Integration**: Works perfectly with Wings state management
- **Lightweight**: Minimal footprint with no external dependencies

## Installation

```bash
npm install @mirawision/react-wings
```

or 

```bash
yarn add @mirawision/react-wings
```

**Note**: This library requires `@mirawision/wings` and React. They will be installed automatically.

## Usage

### Basic Example

```typescript
import React from 'react';
import { useWing } from '@mirawision/react-wings';
import { Wing } from '@mirawision/wings';

interface AppState {
  theme: 'light' | 'dark';
  user: User | null;
  requests?: RequestsState;
}

class AppService extends Wing<AppState> {
  constructor() {
    super({
      theme: 'light',
      user: null,
      requests: {}
    });
  }

  toggleTheme() {
    const currentTheme = this.getState().theme;
    this.setState({ theme: currentTheme === 'light' ? 'dark' : 'light' });
  }
}

function App() {
  const appService = new AppService();
  const [state, controller] = useWing(appService);

  return (
    <div>
      <button onClick={() => controller.toggleTheme()}>
        Current theme: {state.theme}
      </button>
    </div>
  );
}
```

### Advanced State Management

```typescript
import React from 'react';
import { useWing } from '@mirawision/react-wings';
import { Wing } from '@mirawision/wings';

interface UserState {
  users: User[];
  settings: Settings;
  requests?: RequestsState;
}

class UserService extends Wing<UserState> {
  constructor() {
    super({
      users: [],
      settings: {},
      requests: {}
    });
    
    // Define named events
    this.defineEvent('userAdded', (prev, curr) => 
      curr.users.length > prev.users.length
    );
  }

  async fetchUsers() {
    return this.executeRequest('fetchUsers', 
      () => api.getUsers(),
      (users) => this.setState({ users }),
      (error) => console.error(error)
    );
  }

  updateSettings(newSettings: Partial<Settings>) {
    this.setState({ settings: { ...this.getState().settings, ...newSettings } });
  }
}

function UserList() {
  const userService = new UserService();
  const [state, controller] = useWing(userService);

  React.useEffect(() => {
    controller.fetchUsers();
  }, []);

  return (
    <div>
      <h2>Users ({state.users.length})</h2>
      {state.requests?.fetchUsers?.loading && <p>Loading...</p>}
      {state.requests?.fetchUsers?.error && <p>Error: {state.requests.fetchUsers.error}</p>}
      <ul>
        {state.users.map(user => (
          <li key={user.id}>{user.name}</li>
        ))}
      </ul>
    </div>
  );
}
```

### Multiple Components with Shared State

```typescript
import React from 'react';
import { useWing } from '@mirawision/react-wings';
import { Wing } from '@mirawision/wings';

interface SharedState {
  theme: 'light' | 'dark';
  user: User | null;
  notifications: Notification[];
  requests?: RequestsState;
}

// Create a singleton service
const sharedService = new Wing<SharedState>({
  theme: 'light',
  user: null,
  notifications: [],
  requests: {}
});

function ThemeToggle() {
  const [state, controller] = useWing(sharedService);

  return (
    <button onClick={() => controller.setState({ theme: state.theme === 'light' ? 'dark' : 'light' })}>
      Current theme: {state.theme}
    </button>
  );
}

function NotificationBadge() {
  const [state] = useWing(sharedService);
  const unreadCount = state.notifications.filter(n => !n.read).length;

  return (
    <div>
      Notifications: {unreadCount}
    </div>
  );
}

function App() {
  return (
    <div>
      <ThemeToggle />
      <NotificationBadge />
    </div>
  );
}
```

### Event-Driven Components

```typescript
import React from 'react';
import { useWing } from '@mirawision/react-wings';
import { Wing } from '@mirawision/wings';

interface NotificationState {
  notifications: Notification[];
  requests?: RequestsState;
}

class NotificationService extends Wing<NotificationState> {
  constructor() {
    super({ notifications: [], requests: {} });
    
    this.defineEvent('newNotification', (prev, curr) => 
      curr.notifications.length > prev.notifications.length
    );
  }

  addNotification(notification: Notification) {
    this.setState({
      notifications: [...this.getState().notifications, notification]
    });
  }
}

function NotificationListener() {
  const notificationService = new NotificationService();
  const [state, controller] = useWing(notificationService);

  React.useEffect(() => {
    // Subscribe to specific events
    const unsubscribe = controller.subscribeToEvent('newNotification', (prev, curr) => {
      console.log('New notification received!');
      // Show toast or update badge
    });

    return unsubscribe;
  }, []);

  return (
    <div>
      <h3>Notifications ({state.notifications.length})</h3>
      {state.notifications.map(notification => (
        <div key={notification.id}>{notification.message}</div>
      ))}
    </div>
  );
}
```

### Custom Hook with Wings

```typescript
import React from 'react';
import { useWing } from '@mirawision/react-wings';
import { Wing } from '@mirawision/wings';

// Custom hook that combines Wings with additional logic
function useUserManagement() {
  const userService = new Wing<UserState>({
    users: [],
    currentUser: null,
    requests: {}
  });

  const [state, controller] = useWing(userService);

  const login = React.useCallback(async (credentials: LoginCredentials) => {
    return controller.executeRequest('login', 
      () => api.login(credentials),
      (user) => controller.setState({ currentUser: user }),
      (error) => console.error('Login failed:', error)
    );
  }, [controller]);

  const logout = React.useCallback(() => {
    controller.setState({ currentUser: null });
  }, [controller]);

  return {
    state,
    login,
    logout,
    isLoading: controller.isRequestLoading('login'),
    error: controller.getRequestError('login')
  };
}

function LoginForm() {
  const { login, isLoading, error } = useUserManagement();

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    await login({ email: 'user@example.com', password: 'password' });
  };

  return (
    <form onSubmit={handleSubmit}>
      {error && <p>Error: {error}</p>}
      <button type="submit" disabled={isLoading}>
        {isLoading ? 'Logging in...' : 'Login'}
      </button>
    </form>
  );
}
```

## API Reference

### useWing<T extends BaseState, C extends Wing<T>>

React hook that provides seamless integration with Wings state management.

#### Parameters

- `controller: C` - Wings controller instance

#### Returns

- `[T, C]` - Tuple containing current state and controller

#### Type Definitions

```typescript
function useWing<T extends BaseState, C extends Wing<T>>(controller: C): [T, C]
```

#### Usage

```typescript
const [state, controller] = useWing(wingsController);
```

### Features

- **Automatic Subscription**: Automatically subscribes to state changes
- **Automatic Cleanup**: Unsubscribes when component unmounts
- **Type Safety**: Full TypeScript support with generics
- **Performance**: Only re-renders when state actually changes
- **Controller Access**: Provides access to the Wings controller for actions

### Best Practices

1. **Singleton Services**: Use the same Wings instance across multiple components for shared state
2. **Event Handling**: Use Wings events for complex state change reactions
3. **Request Management**: Leverage Wings request lifecycle for loading states
4. **Type Safety**: Always define proper TypeScript interfaces for your state
5. **Cleanup**: The hook automatically handles subscription cleanup

## Contributing

Contributions are always welcome! Feel free to open issues or submit pull requests.

## License

This project is licensed under the MIT License.