@mirawision/react-wings
v1.0.0
Published
React hooks for the Wings state management library, providing seamless integration between React components and Wings state management.
Downloads
5
Readme
@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
npm install @mirawision/react-wingsor
yarn add @mirawision/react-wingsNote: This library requires @mirawision/wings and React. They will be installed automatically.
Usage
Basic Example
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
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
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
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
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: '[email protected]', 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>
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
function useWing<T extends BaseState, C extends Wing<T>>(controller: C): [T, C]Usage
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
- Singleton Services: Use the same Wings instance across multiple components for shared state
- Event Handling: Use Wings events for complex state change reactions
- Request Management: Leverage Wings request lifecycle for loading states
- Type Safety: Always define proper TypeScript interfaces for your state
- 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.
