6.0.2 • Published 5 months ago

mobx-react-routing v6.0.2

Weekly downloads
-
License
MIT
Repository
github
Last release
5 months ago

mobx-react-routing

Usage (with using rootStore)

requires mobx-view-model package usage

1. Create PageViewModelImpl class

This class you will needed for creating your own view model classes
You can implement your own solution based on PageViewModel<Params, ParentViewModel> interface, but PageViewModelBase has a lot of ready solutions like queryParams or pathParams
Only one thing that you should implement is the getParentViewModel and constructor because it requires (in most cases) RootStore

import { PageViewModelBase, RouteDeclaration, RouterStore } from 'mobx-react-routing';
import { ViewModel } from 'mobx-view-model';

export class PageViewModelImpl<
    Params extends AnyObject = EmptyObject,
    ParentViewModel extends ViewModel<any, any> | null = null,
  >
  extends PageViewModelBase<Params, ParentViewModel>
{
  protected router: RouterStore;

  constructor(
    protected rootStore: RootStore,
    routeDeclaration: RouteDeclaration,
    config: ViewModelParams<Params, ParentViewModel>,  
  ) {
    super(routeDeclaration, rootStore.router, config);
    this.router = rootStore.router;
  }

  yourMethodForAllVMs() {
    console.info('log') 
  }
} 

2. Create RouterStoreImpl Class

This class will contains info about all routing and will have all router utilities based on react-router-dom.
You can implement your own solution based on RouterStore interface, but RouterStoreBase has a lot of ready solutions like navigate, blockRoutingIf, blockRouting etc.

import {
  RouterStoreBase,
  RouterStoreParams,
  RouteDeclaration,
  createRoute,
} from 'mobx-react-routing';
import { RouteObject } from 'react-router-dom';

import { PageViewModelImpl } from './page-view-model';

export class RouterStoreImpl extends RouterStoreBase {
  constructor(
    protected rootStore: RootStore,
    params: RouterStoreParams,
  ) {
    super(params);
  }

  // override this method because we need to send rootStore to our view models
  // but default `RouterStoreBase` this method implementation don't know about RootStore
  createRoute(routeDeclaration: RouteDeclaration): RouteObject {
    return createRoute(routeDeclaration, this, (config) => {
      const VM = config.VM as unknown as typeof PageViewModelImpl;
      return new VM(this.rootStore, routeDeclaration, config);
    });
  }
}

3. create instance of your RouterStore implementation

import { Outlet } from "react-router-dom"

const routerStore = new RouterStoreImpl(rootStore, {
  routes: [
    {
      path: '/',
      element: () => <Outlet />,
      children: [
        {
          index: true,
          async loader() {
            const { HomePage, HomePageModel } = await import('@/pages/home');
            return {
              Component: HomePage,
              Model: HomePageModel,
            };
          },
        },
        {
          path: '/my-page',
          async loader() {
            const { MyPagePage, MyPagePageModel } = await import('@/pages/my-page');
            return {
              Component: MyPagePage,
              Model: MyPagePageModel,
            };
          },
        }
      ]
    },
    {
      path: '/login',
      async loader() {
        const { LoginPage, LoginPageModel } = await import('@/pages/login');
        return {
          Component: LoginPage,
          Model: LoginPageModel,
        };
      },
    },
    {
      path: '*',
      Model: NotFoundPageModel,
    },
  ],
  fallbackComponent: () => null,
  errorBoundaryComponent: () => null,
});

4. Attach instance to rootStore

rootStore.router = routerStore;

5. Create Page view model and view

export class HomePageVM extends PageViewModelImpl<{ bar?: string }> {
  mount(): void {
    super.mount();
  }

  unmount(): void {
    super.unmount();
  }

  didUnmount(): void {
    // cleanup here
  }
}

export const HomePageView = observer(({ model }: ViewModelProps<HomePageVM>) => {
  return (
    <div>
      {`foo query param - ${model.queryParams.foo}`}
      {`bar path param - ${model.pathParams.bar}`}
    </div>
  )
})

About path params

Path params should be declared in route declaration firstly

import { RouteDeclaration } from 'mobx-react-routing';
const routeDeclaration: RouteDeclaration =  {
  errorBoundary: ErrorBoundary,
  fallback: GlobalLoader,
  path: '/my-page/:barId',
  async loader() {
    const { HomePageModel } = await import('@/pages/home');
    return {
      Model: HomePageModel,
    };
  },
}

Here is :barId is string path param with key barId. Then in your VM you can declare it using generic

export class HomePageVM extends PageViewModelImpl<{ barId: string }> {
  bars = [
    {
      id: 'kek',
      name: 'Kek',
    },
    {
      id: 'pek',
      name: 'Pek',
    },
  ]

  get barData(){
    return this.bars.find(it => it.id === this.pathParams.barId)
  }
}
5.0.0

5 months ago

6.0.1

5 months ago

6.0.0

5 months ago

6.0.2

5 months ago

3.0.12

8 months ago

3.0.13

8 months ago

3.0.10

8 months ago

3.0.11

8 months ago

4.1.0

7 months ago

4.0.1

7 months ago

4.0.0

8 months ago

4.1.2

7 months ago

4.0.3

7 months ago

4.1.1

7 months ago

4.0.2

7 months ago

3.0.9

9 months ago

3.0.8

9 months ago

3.0.7

9 months ago

3.0.6

9 months ago

3.0.4

9 months ago

3.0.3

9 months ago

3.0.2

9 months ago

3.0.5

9 months ago

1.0.2

10 months ago

1.0.1

10 months ago

1.0.0

10 months ago

3.0.1

9 months ago

3.0.0

9 months ago

1.0.3

10 months ago

2.1.2

9 months ago

2.0.3

9 months ago

2.1.1

9 months ago

2.0.2

9 months ago

2.1.4

9 months ago

2.1.3

9 months ago

2.0.4

9 months ago

2.1.0

9 months ago

2.0.1

9 months ago

2.0.0

9 months ago

0.0.7

12 months ago

0.0.6

12 months ago

0.0.4

12 months ago

0.0.3

12 months ago

0.0.2

12 months ago

0.0.1

12 months ago