General description of the pattern can be found here. But the gist of it is that you divide your code into three sections:
- Model: This is where the business logic and data resides.
- View Model: This code exists to provide the logic necessary for the UI. It directly uses the Model code.
- View: This is the UI code itself and depends on the view model.
If you do MVVM right, your view should be dumb i.e it gets data from the view model and merely displays it.
This is anywhere your data or business logic comes from. If your view model is accessing something simple exposed from matrix-js-sdk
, then the sdk is your model. If you're using something more high level in element-web to get your data/logic (eg: MemberListStore
), then that becomes your model.
- View model is always a custom react hook named like
useFooViewModel()
. - The return type of your view model (known as view state) must be defined as a typescript interface:
inteface FooViewState { somethingUseful: string; somethingElse: BarType; update: () => Promise<void> ... }
- Any react state that your UI needs must be in the view model.
- Views are simple react components (eg:
FooView
). - Views usually start by calling the view model hook, eg:
const FooView: React.FC<IProps> = (props: IProps) => { const vm = useFooViewModel(); .... return( <div> {vm.somethingUseful} </div> ); }
- Views are also allowed to accept the view model as a prop, eg:
const FooView: React.FC<IProps> = ({ vm }: IProps) => { .... return( <div> {vm.somethingUseful} </div> ); }
- Multiple views can share the same view model if necessary.
- MVVM forces a separation of concern i.e we will no longer have large react components that have a lot of state and rendering code mixed together. This improves code readability and makes it easier to introduce changes.
- Introduces the possibility of code reuse. You can reuse an old view model with a new view or vice versa.
- Adding to the point above, in future you could import element-web view models to your project and supply your own views thus creating something similar to the hydrogen sdk.
We started experimenting with MVVM in the redesigned memberlist, you can see the code here.