Service Manager
Service can be a class instance, a function or a React component to handle some pieces of your app logic.
MetaFox platform has a Service Manager called globalContext to manage all services. You can not access the global manager directly but via hooks or saga context.
After passed to the global service manager, a service can be accessible in React components or Saga functions.
In React component:
import {useGlobal} from '@metafox/framework'
const MyComponent (){
const manager = useGlobal();
const {apiClient} = manager
// or simplier
// const {apiClient} = useGlobal();
}In saga functions:
import { getContext } from 'redux-saga/effects';
export function mySagas() {
const { apiClient } = yield * getGlobalContext();
}
globalContextis mutable, changeble. Its service members will be affected by others without being changed or updated.
Class Services
A standard Service class must have bootstrap method, DO NOT define bootstrap as an arrow function.
Let's create the LogService by adding the src/manager/LogService.ts with the following content
/**
* @type: service
* name: logService
**/
import {Manager} from '@metafox/manager'
type LogServiceProps {
// any property here
}
class LogService {
options: LogServiceProps;
constructor(config: LogServiceProps){
this.config = LogServiceProps
}
bootstrap(manager: Manager){
// to do something here.
// return this or void
}
info(message: string){
console.log(message)
}
}Restart dev server, then you can use the LogService with useGlobal hook as the below example:
import useGlobal from '@metafox/framework';
const LoginForm (){
const { logService } = useGlobal();
logService.info('This message is passed by logService')
}Configuration
In the above example, you have created a service named logService. You can pass configuration from root app by adding a section with the same name in manifest.json as below
{
"logService": {
"level": "warn"
}
}Service Manager will pass this configuration to LogService constructor.
If you want to access global configuration in LogService, just use manager.options accesstor.
Functional Service
Sometimes, you would like to declare general functions which can be used anywhere in React components and Sagas. And, you don't want to declare import dependencies everywhere. The good solution is to inject them into Service Manager.
In the next example, we will define a function to generate random string
export default function randomId(): string {
return Math.random()
.toString(36)
.replace(/[^a-z]+/g, '')
.substr(0, 5);
}Now, pass the function to Service Manager
# file src/manager.tsx
const manager = {
logService: LogService,
randomId,
// other manager here
}
export default managerimport {useGlobal} from '@metafox/framework';
const LoginForm (){
const { logService, randomId } = useGlobal();
logService.info('This message is passed by logService')
logService.info('test message id:', randomId());
}React Component Service
In order to inject a React Component across apps without declaration for dependencies, you just need to inject components into the global Service Manager by using inject method
/**
* @type: service
* name: CommentList
*/
export default function CommentList() {}Next, we will declare typings
Create ./src/module.d.ts with the following content
import '@metafox/framework/Manager';
declare module '@metafox/framework/Manager' {
interface Manager {
CommentList?: React.FC<{}>;
}
}Now, you can get CommentList from other components. For example:
import { useGlobal } from '@metafox/framework';
function MyComponent() {
const { CommentList } = useGlobal();
return <CommentList />;
}Core Services
- apiClient
- usePopover
- cookieBackend
- normalization
- preferenceBackend
- dialogBackend
- intl
- createPageParams
- localStore
- compactUrl
- slugify
- copyToClipboard
- useActionControl
- useSession
- useGetItem
- useLoggedIn
- useIsMobile
- usePageParams