Skip to content

Commit 7cfb000

Browse files
authored
Merge pull request #154 from scalprum/introduce-remote-hooks
feat(react-core): add remote hooks interface
2 parents 8671c64 + de92047 commit 7cfb000

21 files changed

+3118
-2
lines changed

docs/README.md

Lines changed: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
# Scalprum Remote Hooks Documentation
2+
3+
Remote Hooks is a powerful feature in Scalprum that allows you to load and execute React hooks from federated modules dynamically. This enables true micro-frontend architecture where not only components but also custom hooks can be shared across applications.
4+
5+
## Overview
6+
7+
Remote Hooks provide a way to:
8+
- **Load hooks from federated modules** - Execute hooks from other applications
9+
- **Dynamic hook management** - Add, remove, and control multiple hooks at runtime
10+
- **Seamless integration** - Works with existing React patterns and TypeScript
11+
- **Isolated execution** - Each hook runs in its own isolated environment
12+
- **Argument updates** - Update hook arguments dynamically without remounting
13+
14+
## Quick Start
15+
16+
```tsx
17+
import { useRemoteHook } from '@scalprum/react-core';
18+
import { useMemo } from 'react';
19+
20+
function MyComponent() {
21+
// ⚠️ Use useMemo when args contain objects/arrays
22+
const args = useMemo(() => [{ initialValue: 0, step: 1 }], []);
23+
24+
const { hookResult, loading, error } = useRemoteHook({
25+
scope: 'counter-app',
26+
module: './useCounter',
27+
args
28+
});
29+
30+
if (loading) return <div>Loading...</div>;
31+
if (error) return <div>Error: {error.message}</div>;
32+
33+
return (
34+
<div>
35+
<p>Count: {hookResult?.count}</p>
36+
<button onClick={hookResult?.increment}>+</button>
37+
</div>
38+
);
39+
}
40+
```
41+
42+
## Documentation
43+
44+
### Core Components
45+
46+
- **[RemoteHookProvider](./remote-hook-provider.md)** - Context provider that enables remote hook functionality
47+
- **[useRemoteHook](./use-remote-hook.md)** - Hook for loading and using individual remote hooks
48+
- **[useRemoteHookManager](./use-remote-hook-manager.md)** - Hook for managing multiple remote hooks dynamically
49+
- **[Remote Hook Types](./remote-hook-types.md)** - TypeScript interfaces and type definitions
50+
51+
### Getting Started
52+
53+
1. **Setup**: The `RemoteHookProvider` is automatically included when using `ScalprumProvider`
54+
2. **Basic Usage**: Use `useRemoteHook` for single hooks or `useRemoteHookManager` for multiple hooks
55+
3. **Argument Handling**: Remember to memoize arguments containing objects or arrays
56+
4. **Error Handling**: Always handle loading and error states
57+
58+
## Architecture
59+
60+
```
61+
┌─────────────────────────────────────┐
62+
│ ScalprumProvider │
63+
│ ┌─────────────────────────────────┐│
64+
│ │ RemoteHookProvider ││
65+
│ │ ┌─────────────────────────────┐││
66+
│ │ │ Your Components │││
67+
│ │ │ - useRemoteHook │││
68+
│ │ │ - useRemoteHookManager │││
69+
│ │ └─────────────────────────────┘││
70+
│ └─────────────────────────────────┘│
71+
└─────────────────────────────────────┘
72+
73+
74+
┌─────────────────────────────────────┐
75+
│ Federated Modules │
76+
│ - ./useCounter │
77+
│ - ./useApiData │
78+
│ - ./useTimer │
79+
└─────────────────────────────────────┘
80+
```
81+
82+
## Key Features
83+
84+
### 🔄 Dynamic Loading
85+
Load hooks from remote modules on-demand, enabling modular architecture.
86+
87+
### 🎯 Isolated Execution
88+
Each remote hook runs in its own isolated environment, preventing conflicts.
89+
90+
### ⚡ Argument Updates
91+
Update hook arguments dynamically without remounting components.
92+
93+
### 🛡️ Type Safety
94+
Full TypeScript support with generic types for hook results.
95+
96+
### 🧹 Automatic Cleanup
97+
Proper resource management and memory leak prevention.
98+
99+
### 📊 Multiple Hook Management
100+
Manage multiple remote hooks dynamically with the hook manager.
101+
102+
## Common Use Cases
103+
104+
### 🔌 Plugin Systems
105+
```tsx
106+
// Load different plugin hooks based on user configuration
107+
const { hookResult } = useRemoteHook({
108+
scope: pluginConfig.scope,
109+
module: pluginConfig.hookModule,
110+
args: [pluginConfig.settings]
111+
});
112+
```
113+
114+
### 📊 Dashboard Widgets
115+
```tsx
116+
// Each widget can use a different remote hook
117+
function Widget({ widgetConfig }) {
118+
const { hookResult, loading } = useRemoteHook({
119+
scope: widgetConfig.app,
120+
module: widgetConfig.dataHook,
121+
args: [widgetConfig.params]
122+
});
123+
124+
return loading ? <Spinner /> : <WidgetDisplay data={hookResult} />;
125+
}
126+
```
127+
128+
### 🔄 A/B Testing
129+
```tsx
130+
// Load different hook implementations for testing
131+
const hookModule = isTestVariantA ? './useFeatureA' : './useFeatureB';
132+
133+
const { hookResult } = useRemoteHook({
134+
scope: 'feature-app',
135+
module: hookModule,
136+
args: [userConfig]
137+
});
138+
```
139+
140+
### 🎛️ Dynamic Feature Loading
141+
```tsx
142+
// Users can enable/disable features that load different hooks
143+
function FeatureManager() {
144+
const manager = useRemoteHookManager();
145+
146+
const enableFeature = (featureName) => {
147+
manager.addHook({
148+
scope: 'features-app',
149+
module: `./use${featureName}Hook`,
150+
args: [{ enabled: true }]
151+
});
152+
};
153+
154+
return (
155+
<div>
156+
<button onClick={() => enableFeature('Analytics')}>
157+
Enable Analytics
158+
</button>
159+
<button onClick={() => enableFeature('Notifications')}>
160+
Enable Notifications
161+
</button>
162+
</div>
163+
);
164+
}
165+
```
166+
167+
## Performance Tips
168+
169+
### ⚠️ Critical: Argument Memoization
170+
```tsx
171+
// ❌ Wrong - causes infinite re-renders
172+
const { hookResult } = useRemoteHook({
173+
scope: 'app',
174+
module: './hook',
175+
args: [{ config: 'value' }] // New object every render!
176+
});
177+
178+
// ✅ Correct - memoized arguments
179+
const args = useMemo(() => [{ config: 'value' }], []);
180+
const { hookResult } = useRemoteHook({
181+
scope: 'app',
182+
module: './hook',
183+
args
184+
});
185+
186+
// ✅ Also correct - primitive values don't need memoization
187+
const { hookResult } = useRemoteHook({
188+
scope: 'app',
189+
module: './hook',
190+
args: [1, 'hello', true] // Primitives are safe
191+
});
192+
```
193+
194+
### 🎯 Efficient Hook Management
195+
- Use `useRemoteHook` for static single hooks
196+
- Use `useRemoteHookManager` for dynamic multi-hook scenarios
197+
- Always clean up hooks when components unmount
198+
- Handle loading and error states appropriately
199+
200+
## Migration Guide
201+
202+
If you're upgrading from a previous version or migrating from other solutions:
203+
204+
1. **Wrap your app** with `ScalprumProvider` (includes `RemoteHookProvider`)
205+
2. **Replace static imports** with `useRemoteHook` calls
206+
3. **Add loading/error handling** for the asynchronous nature of remote hooks
207+
4. **Memoize complex arguments** to prevent infinite re-renders
208+
5. **Update TypeScript types** to use the provided interfaces
209+
210+
## Examples Repository
211+
212+
For complete working examples, see the test applications in this repository:
213+
- `examples/test-app/src/routes/RemoteHooks.tsx` - Basic remote hook usage
214+
- `examples/test-app/src/routes/RemoteHookManager.tsx` - Hook manager examples
215+
- `federation-cdn-mock/src/modules/` - Example remote hook implementations
216+
217+
## Community and Support
218+
219+
- **Issues**: Report bugs and request features on GitHub
220+
- **Discussions**: Join the community discussions for help and best practices
221+
- **Contributing**: See the contributing guide for development setup
222+
223+
## See Also
224+
225+
- [Scalprum Core Documentation](../README.md) - Main Scalprum documentation
226+
- [Module Federation Guide](https://webpack.js.org/concepts/module-federation/) - Understanding federated modules
227+
- [React Hooks Documentation](https://react.dev/reference/react) - React hooks fundamentals

0 commit comments

Comments
 (0)