DEV Community

Cover image for React, TypeScript & Mobx

React, TypeScript & Mobx

Nik Shevchenko on August 23, 2020

The original post: https://shevchenkonik.com/blog/react-typescript-mobx I want to share my R&D process of using React, TS, and Mobx. It’s ab...
Collapse
 
theonlybeardedbeast profile image
TheOnlyBeardedBeast

I like to use getters and setter so I can set store values directly inside the module, a setter automatically becomes an action, no need to decorate it.

  @observable protected _accessToken: Maybe<string> = null;
  @computed public get accessToken(): Maybe<string> {
    return this._accessToken;
  }
  public set accessToken(v: Maybe<string>) {
    this._accessToken = v;
  }
Collapse
 
shevchenkonik profile image
Nik Shevchenko • Edited

Thanks for your feedback!

I know this way, but I don't really understand its advantages over actions.

What is the advantage of that?

Collapse
 
theonlybeardedbeast profile image
TheOnlyBeardedBeast

Shifting action logic into your components/modules. A lot of times it can be handy, but yeah I do too prefer the way you described mobx usage, but I always crete getters and setters.

Collapse
 
gruckion profile image
Stephen Rayner

Okay finished, great work. I would love to see a follow up on unit testing. I am going over this now. I find it strange that you spoke about the importance being able to easily test your service layer but then made your service a singleton. Singletons are hard to test.

It appears you intend to only use your SpotifyService as a wrapper around the SpotifyApi and then test your service only through the store. Do you agree with this?

Also why do you need the service to be in the store? Why not just use the service directly in your component?

Thank you for taking the time to write this. It's the best article I have found so far on enterprise grade design patterns for MobX. Everyone else has half backed solutions that don't scale well.

Collapse
 
shevchenkonik profile image
Nik Shevchenko

Thanks for your feedback!

What is about SpotifyService, I want to use my wrapper around the Spotify API client in the first version of the application, you're right. If I change dependency for my solution, I need to change the only layer and don't rewrite tests.

We can use service directly in our containers (in practice, this turned out to be true) and we can separate business logic between Stores and Containers. My structure has changed after several months of work, I will update this article with the new architecture later. Shortly, new architecture includes two types of stores: Domain Stores & Local Stores. Domain Stores - stores with shared info (responses from backend, some data for many components, etc) in src/stores/, Local Stores - small stores are in the components directory for many components (containers) src/pages/status/ for example. And yes, you can use services inside components in a new architecture approach.

And I switched to Mobx 6 and some examples are outdated... I need time to rewrite the article and update code examples, architecture approaches, etc

Collapse
 
mdekaj profile image
MDEKAJ • Edited

Hi Stephen, could you tell me what RootStoreModel looks like and where it fits in? Thanks

Collapse
 
gruckion profile image
Stephen Rayner

You forgot to tell the user to install uuid @types/uuid mobx. Also you have no examples of RootStoreModel anywhere.

In rootStore.ts you are importing UserStore.ts and AuthStore.ts but then you have your UserStore.ts also importing RootStoreModel from rootStore.

/**
 * import RootStoreModel
 * Dependency cycle detected.eslintimport/no-cycle
 * Module '"./rootStore"' has no exported member 'RootStoreModel'.ts(2305)
 * Peek Problem (βŒ₯F8)
 * Quick Fix... (⌘.)
 **/
import { RootStoreModel } from "./rootStore";
Enter fullscreen mode Exit fullscreen mode
Collapse
 
staschek profile image
Staschek

This works for me:

import React, { FC, createContext, ReactNode, ReactElement } from 'react';
import { RootStore, rootStore } from '../root/root.store';

export const StoreContext = createContext<RootStore>(rootStore);
Enter fullscreen mode Exit fullscreen mode
Collapse
 
mdekaj profile image
MDEKAJ

Hi, is there any examples of RootStoreModel? I'm a bit confused where it fits in...

Collapse
 
gruckion profile image
Stephen Rayner • Edited

Wheres the src? The link is to your github not a specific project. Unsure which project the src is actually in.

github.com/search?q=user%3Ashevche...

You don't appear to have any repos that have mobx-react included within them.

Collapse
 
shevchenkonik profile image
Nik Shevchenko

I'll post the sources when I finish the application and write the second part of the article! I'm working on an application with ML enthusiasts, stay tuned!

Collapse
 
oleksandrkrupko profile image
Oleksandr Krupko

Thanks for a really good article that embraces the best practices of writing large scale applications and increases overall code quality! Keep it up, waiting for your future articles man!

Collapse
 
abhigk profile image
Abhi

I am trying to find the second part of the article. Where is the link?

Collapse
 
mrjjwright profile image
John Wright

How do you like the actual observable/computed programming model?

Collapse
 
shevchenkonik profile image
Nik Shevchenko

I use Mobx at my projects sometimes and I have never regretted choosing it. I find it convenient to develop large systems, the main point is to organize services, stores, and classes correctly. But this one is only one way to organize you know, it depends on what you compare it too ;)

Collapse
 
aralroca profile image
Aral Roca

Does anyone know of an alternative to hoist-non-react-statics to copy the react statics?

hoist-non-react-statics is heavier than my HoC lib... πŸ€ͺ