Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🚀 Proposal: MobX 6: 🧨drop decorators,😱unify ES5 and proxy implementations, 💪smaller bundle #2325

Closed
mweststrate opened this issue Apr 1, 2020 · 149 comments

Comments

@mweststrate
Copy link
Member

mweststrate commented Apr 1, 2020

MobX 6

Hi folks, I've tinkered a lot about MobX 6 lately, so I want to layout the vision I have currently

Goals

🧨 1. Become compatible with modern ES standards

Let's start with the elephant in the room.
I think we have to drop the support for decorators.
Some have been advocating this for years, others totally love decorators.
Personally I hate to let decorators go. I think their DX and conciseness is still unparalleled.
Personally, I am still actively engaged with TC-39 to still make decorators happen, but we are kinda back to square one, and new proposal will deviate (again) from the implementation we already have.

Dropping decorators has a few advantages, in order of importance (imho)

  1. Become compatible with standard modern JavaScript Since fields have not been standardized with [[define]] over [[set]] semantics, all our decorator implementations (and the decorate utility) are immediately incompatible with code that is compiled according the standard. (Something TypeScript doesn't do, yet, by default, as for TS this is a breaking change as well, unrelated to decorators). See #2288 for more background
  2. MobX will work out of the box in most setups MobX doesn't work with common out-of-the-box setup in many tools. It doesn't work by default in create-react-app which is painful. Most online sandboxes do support decorators (MobX often being one of the few reasons), but it breaks occasionally. Eslint requires special setup. Etc. etc. Dropping decorators will significantly lower the entry barrier. A lower entry barrier means more adoption. More adoption means more community engagement and support, so I believe in the end everyone will win.
  3. Less way to do things currently it is possible to use MobX without decorators, but it is not the emphasized approached, and many aren't even aware of that possibility. Reducing the amount of different ways in which the same thing can be achieved simplifies documentation and removes cognitive burden.
  4. Reduce bundle size A significant amount of MobX is decorator chores; that is because we ship with basically three implementations of decorators (TypeScript, Babel, decorate). I expect to drop a few KB by simply removing them.
  5. Forward compatibility with decorators I expect it will (surprisingly) be easier to be compatible with decorators once they are officially standardized if there is no legacy implementations that need to be compatible as well. And if we can codemod it once, we can do that another time :)

The good news is: Migrating a code base away from decorators is easy; the current test suite of MobX itself has been converted for 99% by a codemod, without changing any semantics (TODO: well, that has to be proven once the new API is finalized, but that is where I expect to end up). The codemod itself is pretty robust already!

P.s. a quick Twitter poll shows that 2/3 would love to see a decorator free MobX (400+ votes)

😱 2. Support proxy and non-proxy in the same version

I'd love to have MobX 6 ship with both Proxy based and ES5 (for backward compatibility) implementations. I'm not entirely sure why we didn't combine that anymore in the past, but I think it should be possible to support both cases in the same codebase. In Immer we've done that as well, and I'm very happy with that setup. By forcing to opt-in on backward compatibility, we make sure that we don't increase the bundle size for those that don't need it.

P.S. I still might find out why the above didn't work in the past in the near future :-P. But I'm positive, as our combined repo setup makes this easier than it was in the past, and I think it enables some cool features as well, such as detection of edge cases.

For example we can warn in dev mode that people try to dynamically add properties to an object, and tell them that such patterns won't work in ES5 if they have opted-in into ES5 support.

💪 3. Smaller bundle

By dropping decorators, and making sure that tree-shaking can optimize the MobX bundle, and mangling our source aggressively, I think we can achieve a big gain in bundle size. With Immer we were able to halve the bundle size, and I hope to achieve the same here.

To further decrease the build, I'd personally love to drop some features like spy, observe, intercept, etc. And probably a lot of our low-level hooks can be set up better as well, as proposed by @urugator.

But I think that is a bridge too far as many already rely on these features (including Mobx-state-tree). Anyway I think it is good to avoid any further API changes beyond what is being changed in this proposal already. Which is more than enough for one major :). Beyond that, if goal 2) is achieved, it will be much easier to crank out new majors in the future :). That being said, If @urugator's proposal does fit nicely in the APIs proposed below, it might be a good idea to incorporate it.

4. 🛂Enable strict mode by default

The 'observed' one, that is.

🍿API changes

UPDATE 22-5-20: this issue so far reflected the old proposal where all fields are wrapped in instance values, that one hasn't become the solution for reasons explained in the comments below

This is a rough overview of the new api, details can be found in the branch.

To replace decorators, one will now need to 'decorate' in the constructor. Decorators can still be used, but they need to be opted into, and the documentation will default to the non-decorator version. Even when decorators are used, a constructor call to

class Doubler {
  value = 1 

  get double () {
    return this.field * 2
  }

  increment() {
    this.value++
  }

  constructor() {
    makeObservable(this, {
      value: observable,
      double: computed,
      increment: action
    })
  }
}
  • If decorators are used, only makeObservable(this) is needed, the type will be picked from the decorators
  • There will be an makeAutoObservable(this, exceptions?) that will default to observable for fields, computed for getters, action for functions

Process

    1. Agree on API
    1. Implement code mod
    1. Implement API changes
    1. Try to merge v4 & v5
    1. Try to minimize build
    1. Update docs (but keep old ones around)
    1. Provide an alternative to keep using decorators, e.g. a dedicated babel transformation or move current implementation to separate package?
    1. Write migration guide
    1. Beta period?
    1. Create fresh egghead course

Timeline

Whatever. Isolation makes it easier to set time apart. But from time to time also makes it less interesting to work on these things as more relevant things are happening in the world

CC: @FredyC @urugator @spion @Bnaya @xaviergonz

@mweststrate mweststrate changed the title Proposal: MobX 7: drop decorators, unify ES5 and proxy implementations, smaller bundle 🚀 Proposal: MobX 7: 🧨drop decorators,😱unify ES5 and proxy implementations, 💪smaller bundle Apr 1, 2020
@spion
Copy link

spion commented Apr 1, 2020

You probably already know this 😀 but here is my strong vote against removing decorators. I frankly don't care what TC39 think, decorators are here to stay. I'm not removing them from any codebase and I will strongly advocate against any removal from any library as well.

IMO its time to stand our ground.

@Bnaya
Copy link
Member

Bnaya commented Apr 1, 2020

Quick thought:
What about adding decorators with external package to mobx core?
"mobx-decorators"
Do we expose the needed low-level primitives?

@urugator
Copy link
Collaborator

urugator commented Apr 1, 2020

observable(1) cannot be <T>(value: T, options?) => T (as it must return some box), correct?
How does this work with class field value: int = observable(1)?

I worry that this data/metadata duality will backfire eventually. If I remember correctly we had something like this in Mobx2.

Had an idea like:
EDIT: nevermind bad idea...

@xaviergonz
Copy link
Contributor

xaviergonz commented Apr 1, 2020

🧨 1. Become compatible with modern ES standards

Personally I also hate what TC39 is doing to decorators, and maybe it is one of those things that should be left to transpilers. Maybe there could be a mobx-decorators v7 package for those that want to keep using with them? (and also could make adoption easier).

😱 2. Support proxy and non-proxy in the same version

Sounds awesome.

💪 3. Smaller bundle

To further decrease the build, I'd personally love to drop some features like spy, observe, intercept, etc. And probably a lot of our low-level hooks can be set up better as well, as proposed by @urugator.

As long as there are alternatives it should be ok (mobx-keystone for example relies on both observer, intercept and then some more). But the more changes there are, the more likely current mobx libs will become incompatible and stop adoption.

🍿API changes

autoInitializeObservables will reflect on the instance, and automatically apply observable, computed and action in case your class is simple

When is a class considered simple? When there are no fields with mobx "decorators"?
If so, it might be confusing to have a "simple" class, then add an action and see how the whole class becomes something totally different.

observable and extendObservable does currently convert methods to observable.ref's instead of actions by default.

I think 99% of the time you'd want functions to become actions (and actually I didn't even know this observable.ref was the case), so as long as this is explained on some release notes it should be ok.
In the worst case there could be a global flag like "versionCompatibility": 5 or similar that actually makes it work as usual for those migrating from an older version and that prints in the console a warning when a function is passed to observer so you can eventually fix it and remove the flag.

@kubk
Copy link
Collaborator

kubk commented Apr 1, 2020

To further decrease the build, I'd personally love to drop some features like spy, observe, intercept, etc.

mobx-logger depends on spy as well as mobx-remotedev (Redux devtools for Mobx). Is there another way to listen to observable mutations in Mobx?

@danielkcz
Copy link
Contributor

danielkcz commented Apr 2, 2020

You probably already know this 😀 but here is my strong vote against removing decorators. I frankly don't care what TC39 think, decorators are here to stay. I'm not removing them from any codebase and I will strongly advocate against any removal from any library as well.

IMO its time to stand our ground.

@spion Frankly, that is just a rant. Michel wrote the pros of removing decorators. If you want to "stand ground" and "strongly advocate", then please make constructive counter-arguments instead of just "I like them".

Personally, I am on the other side of this war and I never liked decorators. This fresh new look definitely makes sense to me. However, if there is some possibility to keep decorators support in the external package as it was suggested, then it's probably something we should do. If people feel the necessity to wear a foot gun, it's their choice. Besides, it would be suddenly more apparent where that decorator magic is coming from and that it's something optional.

@webernir

This comment has been minimized.

@mweststrate
Copy link
Member Author

mweststrate commented Apr 2, 2020 via email

@mweststrate
Copy link
Member Author

I worry that this data/metadata duality will backfire eventually. If I remember correctly we had something like this in Mobx2.

Yeah, I think that is the part I like the least as well. Maybe we should introduce a separate 'marker' to for observable properties, e.g. field = tracked(value), and use observable only for instantiating collections (mostly relevant when not using classes). But not sure whether we should have an alternative for computed as well, and what would be a good name.

@benjamingr
Copy link
Member

I like decorators but I totally understand this direction. There are a few reasons for this, let me try and make Gorgi's case @FredyC :

  • Decorators are explicit, I get to say exactly what is reactive, no fields are reactive implicitly.
  • Decorators are declarative, it feels like another meta-property of the type (like private, or readonly) which addresses a concern of the field (reactivity).
  • Decorators are the way this is done in other systems (like Angular) and languages (like UI systems in C# or Python)
  • Decorators have been the "mostly standard MobX way" for a while and removing them is 5 years of breakage.

Also, removing something so widely used because the spec committee can't proceed always leaves a bad taste in my mouth. Even as I acknowledge they are all acting in good faith and that decorators are a hard problem for engines because of the reasons outlined in the proposal (I've been following the trapping decorators discussions).

@benjamingr
Copy link
Member

Some API bikeshedding:

Decorators

class Doubler {
  @observable value = 1

  @computed get double() {
    return this.field * 2
  }

  @action increment() {
    this.value++
  }
}

Michel's original:

class Doubler {
  value = 1

  get double() {
    return this.field * 2
  }

  increment() {
    this.value++
  }

  constructor() {
    autoInitializeObservables(this)
  }
}

Subclass:

class Doubler extends ObservableObject {
  value = 1

  get double() {
    return this.field * 2
  }

  increment() {
    this.value++
  }
}

Can be interesting, but is not very good in terms of coupling. Or with a class wrapper:

const Doubler = wrapObservable(class Doubler {
  value = 1

  get double() {
    return this.field * 2
  }

  increment() {
    this.value++
  }
});

@danielkcz
Copy link
Contributor

  • Decorators have been the "mostly standard MobX way" for a while and removing them is 5 years of breakage.

Don't forget there will be a codemod to make most of the hard work for you, so this isn't really a valid argument. Besides, nobody is forced to upgrade to the next major. It probably depends if we will be able to maintain v4 & v5 or abandon those. And if we separate package will exist for decorators then it might be fairly non-braking change.

Btw, @mweststrate Just realized, why MobX 7? Do we need to skip V6 for some reason? 🤓

@mweststrate
Copy link
Member Author

mweststrate commented Apr 2, 2020 via email

@benjamingr
Copy link
Member

@FredyC hey, I would prefer it if we avoided terms like "isn't really a valid argument" when talking about each other's points.

I think having a common and standard way to do something in a library (decorators) is definitely a consideration and API breakage is a big concern - even with a codemod. I think removing decorators is unfortunately the way forward - but breaking so much code for so many users definitely pains me.


@mweststrate subclassing is also not very ergonomic and mixes concerns here IMO.

I'm not sure I understand the wrapping issue in TypeScript but I know there are challenges involving it. Wrapping doesn't actually have to change the type similarly to initializeObservables:

class Doubler {
   ...
}
initializeObservables(Doubler); // vs in the constructor

Or even decorate the type in a non-mutating way:

const ReactiveDoubler = initializeObservables(Doubler); // vs in the constructor

Wouldn't it make more sense to initializeObservables on the type and not on the instance? Is there any case I'd want to conditionally make an instance reactive but not have several types?

@mweststrate
Copy link
Member Author

mweststrate commented Apr 2, 2020

@benjamingr yeah that is exactly what decorate does so far. The problem is that initializeObservables won't see the fields if invoked on the type, field x = y is semantically equivalent to calling defineProperty(this, 'x', { value: y }) in the constructor, so the field does never exist on the type.

So even if you don't know the fields, but you do specify them on the type, you can't decorate the type to trap the assignment, because the new property will simply hide it. I think it is still a weird decisions to standardize [[define]] over [[set]] semantics, which has rarely any merits, and deviates totally from what TS and babel were doing. But that is how it is.....

@spion
Copy link

spion commented Apr 2, 2020

@FredyC It is not a rant, it's a constructive comment. Decorators are widely used throughout the community, with large projects such as Angular, NestJS and MobX taking advantage of them. Thousands of projects depend on them. For TC39 to block their standardization process strikes me as extremely irresponsible, and the arguments for doing so are severely under-elaborated (a vague 3-pager does not an elaboration make - try harder TC39).

The advantages that @mweststrate mentioned are largely the fault of this lackluster standardization which means the argument is cyclic: it ultimately comes down to "we're not supporting decorators because decorators are not well supported". Language features that aren't yet standardized are never well supported, the argument can be used to justify not adopting any new language feature. So if TC39 "paves cowpaths" and everyone adopted this way of thinking, the language would stop evolving.

(Clearly, this is not a new feature so there is some merit to the "not likely to be supported" argument implying its a good idea to give up on them. I just wanted to bring to the table that the other approach - standing our ground - might be good too)

For those of us who do care about decorators, what are our options? Our only hope is to stand our ground, keep using them and keep advocating their standardization. Even if TC39 doesn't standardize them, development within TypeScript might continue, addressing the remaining gaps WRT reflection and types.

If you don't care about decorators, please stay out of it. They have always been optional in MobX and will continue to be optional - no one is forcing you to use them. If you care about a smaller bundle, they can be offloaded to a side module (but I maintain they should still have a first-class place in the documentation)

@benjamingr
Copy link
Member

@mweststrate is there anything stopping us from trapping construct and intercepting those fields then or setting a proxy?

Such an initializeObservables wouldn't do anything until an object is constructed and then return a proxy (or decorate) when the constructor is called.

That is:

  • Someone calls makeReactive/nitializeObservable and passes it a class
  • That someone gets a new class back that is a proxy over the old class. (vs. a proxy for the instance by intercepting construct)
  • When that class is constructed - we intercept the fields at the end of the constructor (after invoking it) and make it reactive. (Or with proxies we just return a proxy since we don't need to do work-per-field).

That way the fact the field is not a part of the type doesn't really matter - since while it looks like we are decorating the prototype/class we are actually decorating the instance and only "decorating" the construct on the type.

@benjamingr

This comment has been minimized.

@spion

This comment has been minimized.

@benjamingr

This comment has been minimized.

@spion

This comment has been minimized.

@trusktr
Copy link

trusktr commented Sep 8, 2020

Perhaps if the API were as follows, the construction performance could be improved at a slight cost in DX:

class Foo {
  @observable foo = 123

  constructor() {
    makeObservable(this, Foo)
  }
}

class Bar extends Foo {
  @observable bar = 456

  constructor() {
    super()
    makeObservable(this, Bar)
  }
}

class Baz extends Bar {
  @observable baz = 'hello'

  constructor() {
    super()
    makeObservable(this, Baz)
  }
}

const baz = new Baz

autorun(() => {
  console.log(baz.foo, baz.bar, baz.baz)
})

It would be faster because the decorators could map constructors to keys (f.e. Ctor[symbol].push(propName)), and the
makeObservable calls would not have to traverse the prototype and not have to check own props to see if they exist.

@olee
Copy link

olee commented Sep 8, 2020

@trusktr I think this is an interesting idea and one should not forget performance in the whole matter.
Are there any performance comparisons yet between mobx 4/5/6?

@trusktr
Copy link

trusktr commented Sep 9, 2020

I haven't made any comparisons, but if we have 1000 instances of the above Baz, then in the MobX 5 version there would have only been 3 decorate calls (O(1)), while in the MobX 6 version there will be 3000 makeObservable calls (O(n), previous optimization idea aside).

Not sure if it is worth it, but perhaps having both is an option: makeObservable(this) is more concise and fine for most cases, while makeObservable(this, Baz) could be an optional way to call it that entirely short-circuits the prototype traversal and the prop checking (still doesn't eliminate the 3000 calls).

@urugator
Copy link
Collaborator

then in the MobX 5 version there would have only been 3 decorate calls (O(1))

Even in Mobx4/5 there is a logic similar to makeObservable that runs per instance, it just happens lazily when you access a decorated field for the first time.

initializeInstance(this)

Moving the call to constructor actually makes it a lot less complicated.
I don't say a one is necessarily faster than other, just saying it's not simply 3 vs 3000 calls.

@mweststrate
Copy link
Member Author

mweststrate commented Sep 10, 2020

We have benchmark tests for creating 100.000 class instances. The results are as follow:

version test creation updates
6 typescript + decorators 7616 11319
6 typescript + makeObservable 9029 13025
6 babel + decorators 7801 11762
6 babel + makeObservable 9266 13490
5 typescript + decorators 2525 5140
5 babel + decorators 2755 5426
4 typescript + decorators 2766 7416
4 babel + decorators 2813 7470

So things have became a bit slower indeed. I can imagine there are some optimisation opportunities here and there still. But the change isn't in a different order of magnitude, and so far object creations or updates being to slow have never been reported as an issue with mobx (IIRC), so I'm not too worried for now; it is quite likely you hit other bottlenecks first when dealing with 100k object, so without real life scenarios in which MobX object interactions prove to be the bottleneck, I'm not worried at this moment.

I suspect however that the primary reason for the slow-down is the babel / TS config change to use [define] instead of [set] to initialise fields, but I didn't actually measure it as no benchmarking tool seems allow playing quickly with babel options. But see this link for why that might matter a lot

@olee
Copy link

olee commented Sep 10, 2020

Ouch - that link you shared really shows how bad this change regarding define semantics for class fields is.
Would it be possible to run a v6 benchmark without the transpilation to define semantics enabled so it can be exluded from the comparison?

@mweststrate
Copy link
Member Author

mweststrate commented Sep 11, 2020 via email

@bb
Copy link
Contributor

bb commented Sep 11, 2020

Edit: Fixed in mobx@6.0.0-rc.8

Not sure if this worth a separate issue... I decided to post it here as it's something new introduced with MobX 6:

When upgrading from TypeScript 3.9.7 to TypeScript 4.0.2 I'm receiving an error when providing a second argument to makeAutoObservable. I assume something was made stricter in newer TS version and MobX needs to catch up (but I'm not really sure).

Here's a code sandbox, relevant section highlighted: https://codesandbox.io/s/ecstatic-lake-s93v4?file=/src/App.tsx:351-480

The Code Sandbox is currently fine as it is using TypeScript version 3.9.7 which can be seen in the lower right corner. It seems to me that I cannot change the TS version inside CodeSandbox.

However, when downloading that via Menu File→Export as Zip, doing npm install and then running react-scripts build I get the following error:

TypeScript error in /Users/bb/Downloads/s93v4/src/App.tsx(16,30):
Argument of type '{ exampleShallowMap: Annotation & PropertyDecorator; exampleShallowArray: Annotation & PropertyDecorator; }' is not assignable to parameter of type 'Partial<Record<keyof this, AnnotationMapEntry>>'.  TS2345

    14 |
    15 |   constructor() {
  > 16 |     makeAutoObservable(this, {
       |                              ^
    17 |       exampleShallowMap: observable.shallow,
    18 |       exampleShallowArray: observable.shallow
    19 |     });

The same error is also marked in latest VS Code (August Update, which is using TS 4.0.2) but was not yet marked in the July Update (which is using TypeScript 3.9.7 like the Code Sandbox).

@olee
Copy link

olee commented Sep 13, 2020

Secondly object creating and field assignments is
probably like 0.01% of the work your app is doing and unlikely to be the
bottleneck of your application

I'm not sure about that - especially when having something like a virtual repeat which loads pages of entities, even small delays could cause the view to lag.
However I guess you are right - more often deserialization etc. takes up waay more time than something like class instantiation (though I would like to test this out sometime)

@stephy
Copy link

stephy commented Sep 16, 2020

Honestly... I am sad to see the decorators go. I am big fan of their simplicity and clarity. I am happy to see that there will be a work around to be able to continue to use them. However, I am thinking it will be quick to adapt to the new syntax

I am guessing this choice was probably a good call. Maybe now without decorators I am hopeful I will be able to convey to people how amazing Mobx is and at least I won't hear the decorators excuse anymore. I have never seen an "@" sign scare so many people.

@olee
Copy link

olee commented Sep 17, 2020

@mweststrate if you have some time, could you give us an update on what is left to do before we can maybe get a mobx v6 beta and when we (roughly) might expect a v6 release?

@bb
Copy link
Contributor

bb commented Sep 17, 2020

@olee -- I don't know about the release schedule but I'm using RC7 in production already. See also https://www.npmjs.com/package/mobx/v/6.0.0-rc.7?activeTab=versions. Except for my issue with TS 4.x described above, it works fine (with mobx-react-lite v.3 beta https://www.npmjs.com/package/mobx-react-lite/v/3.0.0-beta.1).

However, you should be aware that there's no mobx-utils prerelease yet. See mobxjs/mobx-utils#276.

@mweststrate
Copy link
Member Author

@bb thanks for pointing that out, after upgrading MobX to 4.0.2 the internal tests fail as well

@mweststrate
Copy link
Member Author

New beta available:

mobx@6.0.0-rc.8
mobx-react-lite@3.0.0-beta.1
mobx-react@6.0.0-rc.4
mobx-utils@6.0.0-rc.1
Docs: https://deploy-preview-2327--mobx-docs.netlify.app/readme
Migration guide: https://deploy-preview-2327--mobx-docs.netlify.app/faq/migrate-to-6.html

I don't expect any API changes anymore, still polishing docs

@bb
Copy link
Contributor

bb commented Sep 18, 2020

@mweststrate I confirm the TS 4.0.2 issue is fixed. Thanks a lot; both for fixing that and for releasing the mobx-utils RC.

@roeycohen
Copy link

roeycohen commented Sep 20, 2020

so @mweststrate, decorators are out in v6? It doesn't exists in the new docs anymore, but will using them fail?

@ar7casper
Copy link

ar7casper commented Sep 21, 2020

@roeycohen

so @mweststrate, decorators are out in v6? It doesn't exists in the new docs anymore, but will using them fail?

image

https://deploy-preview-2327--mobx-docs.netlify.app/best/decorators.html#how-to-enable-decorator-support

@yordis
Copy link

yordis commented Sep 21, 2020

@mweststrate is there any concerns using MST with v6?

@episage
Copy link

episage commented Sep 21, 2020

I'd like to note that mobx@6.0.0-rc.8 does not seem to be tree shakable. No matter what you import, you end up with the whole bundle in all cases. Is this intentional?

image
Source: https://bundlephobia.com/result?p=mobx@6.0.0-rc.8

@mweststrate
Copy link
Member Author

@yordis there is an open PR that should support MobX 6 fully. But I do not intend to release it personally as there are enough people and companies actually using the thing, benefiting from it but not really contributing back. So I leave releasing and double checking the update to the community, but the PR is here: mobxjs/mobx-state-tree#1569

@mweststrate
Copy link
Member Author

@episage if I run it to terser's tree-shaking, I get results between 13.9 and 15.2 k depending on the imports (yarn test:size in the project). I think things could be better, so if someone wants to play with that feel free to take a stab at it, but I won't be further looking into it.

@yordis
Copy link

yordis commented Sep 21, 2020

@mweststrate I am sorry, I am confused with what you said.

But I do not intend to release it personally as there are enough people and companies actually using the thing, benefiting from it but not really contributing back

Are you saying that people are using the package but they don't contribute back, therefore, you will no release a new version using mobx@v6?

So I leave releasing and double checking the update to the community

So we (the community) should take the lead on upgrading MST itself, and verify that works

Is that correct?

@mweststrate
Copy link
Member Author

mweststrate commented Sep 21, 2020 via email

@israelKusayev
Copy link

Hey, I started to try mobx 6, and I have few questions and problems

here is the commit with the new mobx setup
reflexology/client-V2@b283e11

  1. The example of combining multiple stores is a little bit confusing because all the stores are in one file.

    Do I have to pass the instance of rootStore to all other stores? or it is just to share the data between the stores?

    Also I'm getting typescript error about { rootStore: false }
    Argument of type '{ rootStore: boolean; }' is not assignable to parameter of type 'AnnotationsMap<this, never>'. Object literal may only specify known properties, and 'rootStore' does not exist in type 'AnnotationsMap<this, never>'.ts(2345)

  2. I saw the recommendation to use react context to insert the rootStore into the component tree, and I found this example, I guess if I have rootStore with multiple stores, I should pass the whole rootStore (instead of one store like you did in the example)

    now when I want to use the store in react FC, do I need to do const rootStore = useContext(StoreContext);?

    How can I get one store?

Thanks

@mweststrate
Copy link
Member Author

Closing since released: https://michel.codes/blogs/mobx6

For any follow up questions, open a separate issue.

@mobxjs mobxjs locked as off-topic and limited conversation to collaborators Sep 30, 2020
@mweststrate mweststrate unpinned this issue Sep 30, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests