6.0.2 • Published 6 months ago

mobx-react-routing v6.0.2

Weekly downloads
-
License
MIT
Repository
github
Last release
6 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

6 months ago

6.0.1

6 months ago

6.0.0

6 months ago

6.0.2

6 months ago

3.0.12

9 months ago

3.0.13

9 months ago

3.0.10

9 months ago

3.0.11

9 months ago

4.1.0

8 months ago

4.0.1

8 months ago

4.0.0

9 months ago

4.1.2

8 months ago

4.0.3

8 months ago

4.1.1

8 months ago

4.0.2

8 months ago

3.0.9

10 months ago

3.0.8

10 months ago

3.0.7

10 months ago

3.0.6

10 months ago

3.0.4

10 months ago

3.0.3

10 months ago

3.0.2

10 months ago

3.0.5

10 months ago

1.0.2

11 months ago

1.0.1

11 months ago

1.0.0

11 months ago

3.0.1

10 months ago

3.0.0

10 months ago

1.0.3

11 months ago

2.1.2

10 months ago

2.0.3

10 months ago

2.1.1

10 months ago

2.0.2

10 months ago

2.1.4

10 months ago

2.1.3

10 months ago

2.0.4

10 months ago

2.1.0

10 months ago

2.0.1

10 months ago

2.0.0

10 months ago

0.0.7

1 year ago

0.0.6

1 year ago

0.0.4

1 year ago

0.0.3

1 year ago

0.0.2

1 year ago

0.0.1

1 year ago