inversify-react-mvvm
v0.0.4
Published
Lightweight and opinionated mvvm glue/helper code for React/Inversify.
Downloads
17
Maintainers
Readme
Lightweight and opinionated mvvm glue/helper code for React/Inversify.
Motivation
For projects that embrace a MVVM pattern you usually end up writing some glue code to connect your React Components with the designated ViewModel.
This micro-library helps to reduce the aforementioned glue code by trying to make it as easy as possible to connect the two worlds.
Dependencies
This library is using inversify as a way to resolve/instantiate the view models, making it a hard dependency. If that is not your taste, feel free to just take the parts you like 😉
Installation
yarn add inversify-react-mvvm
# or
npm install inversify-react-mvvm
Usage
The ViewModel
All view models have to extend ViewModel
. You don't have to implement any of the following methods though, these are for demonstration purposes.
provideByClass
is an extension to provide
from inversify-inject-decorators allowing you to register the decorated class by class reference in inversify
. It is not a requirement to do it like that, you can also register your view models explicitely in your container.
You can use provideByClass
not only for ViewModels, but also for your services/etc.
⚠️ provideByClass
registeres the view models as Singleton
.
// ExampleViewModel.tsx
import { ViewModel, provideByClass } from 'inversify-react-mvvm';
import { useParams } from 'react-router';
import { inject } from 'inversify';
import { SomeService } from './services/some-service.ts';
@provideByClass
export class ExampleViewModel extends ViewModel {
// you can make full use of property injection
@inject(SomeService) private someService!: SomeService;
public content = "Wow, such empty";
private params!: { id: string };
public _bind = () => {
// by overriding this method you can use hooks/effects/state
this.params = useParams();
}
public onLoad = () => {
console.log('~= componentDidMount');
// place your favorite ajax calls here
}
public onLeave = () => {
console.log('~= componentWillUnmount');
// detach event handlers, dispose, etc.
}
}
The (consumer) component
// Example.tsx
import { ExampleViewModel } from './ExampleViewModel';
import { useVm } from 'inversify-react-mvvm';
export const Example = (props: any) => {
const vm = useVm(MenuViewModel);
return (
<div>{ vm.content }</div>
);
};
The configuration
// App.tsx (or alike)
import { buildProviderModule } from 'inversify-binding-decorators';
import { Container } from 'inversify';
import { BrowserRouter as Router } from 'react-router-dom';
import { InversifyProvider } from 'inversify-react-mvvm';
const container = new Container();
// registers all bindings from inversify-inject-decorators
container.load(buildProviderModule())
export const App = () => {
return (
<InversifyProvider container={container}>
<Router>
<Example />
</Router>
</InversifyProvider>
)
}