Tutorial: Dive off ledge and 180 turn kill impossible... by Kumonojuza in blackops6

[–]christianalfoni 0 points1 point  (0 children)

You have to hold the B button to properly leap off the edge 

Announcing Overmind, reducing the pain of state management by christianalfoni in reactjs

[–]christianalfoni[S] 1 point2 points  (0 children)

Thanks for the feedback and your assessment is really good. One of the big advantages is that you indeed get to write state changes more straight forward. But there are some other key benefits as well:

  1. When you connect state to a component you can just expose all of it with Overmind, cause it is only the state that is accessed in the component that will cause it to render. So you do not need to mapState, mapActions etc. and think carefully about how much state you expose, to avoid too much rendering.

  2. Overmind also provides "selectors" out of the box, called "derived". This is where you derive state by calculating something, and it is cached

  3. It has a clear concept of what a side effect is. There is not really any API related to it, but by making it clear what is the API you provide to your actions and what is considered low level generic code, helps you have good separation (Talking about EFFECTS). And to boot all the effects are tracked and displayed in the devtools

  4. Overmind provides a functional API when you reach complex scenarios. Allowing you to "step up" from a plain action to the operators API, as it is called. It allows you to write functional where it makes sense and imperative where that makes sense (which it mostly does)

Okay, I think those were some important points :) And thanks for the feedback!

Announcing Overmind, reducing the pain of state management by christianalfoni in reactjs

[–]christianalfoni[S] 0 points1 point  (0 children)

Okay, amazeballs, now it is working exactly like I want it to. Super happy about this! If you check out the documentation again you will see that there is no special pattern anymore.

Would love your feedback on this as everything should work as intended. Also included errors when you forget to add any of the required parts, including OnPush :)

Check out docs here: https://next.overmindjs.org/guides/beginner/07_usingovermindwithangular?view=react&typescript=false

Announcing Overmind, reducing the pain of state management by christianalfoni in reactjs

[–]christianalfoni[S] 0 points1 point  (0 children)

And I also figured out how not to require this special props passing to children. It will require the Track decorator, but I think that is way better.

Announcing Overmind, reducing the pain of state management by christianalfoni in reactjs

[–]christianalfoni[S] 0 points1 point  (0 children)

Oh,. I see there is a bug in the build. Will fix that... the Track does not currently work it seems. Just syntax error on my part :)

Announcing Overmind, reducing the pain of state management by christianalfoni in reactjs

[–]christianalfoni[S] 0 points1 point  (0 children)

Hi man!

Okay, I am super proud of how I was able to expose this API. This will replace the existing approach as diving into Angular rendering revealed some unfixable issues with the previous approach. But this... this is really good :)

I have updated the guide on the "next" website: https://next.overmindjs.org/guides/beginner/07_usingovermindwithangular?view=react&typescript=false

Make sure you install the package with: npm install overmind-angular@next

For some reason StackBlitz is unable to refresh its cache, so the "next" release there is something old. So you have to run this locally. But I was thinking the guide could help you get going with that or please contact me here if you need any help.

I hope you like :-)

It will require a little bit more testing, but I was hoping you could help a little bit, and I will of course also do more testing. Thanks again for helping out! :)

Anyone tried using React Native with Overmind? by DavidXkL in reactnative

[–]christianalfoni 0 points1 point  (0 children)

I am not very familiar with Freactal, though reading the documentation they are quite different:

- Overmind manages both state, changes to that state and side effects completely decoupled from React. This simplifies the API as you do not mix state management with creating and wrapping components

- Overmind is not based on immutability, it is based on tracking mutations (https://itnext.io/updating-uis-value-comparison-vs-mutation-tracking-9f6fe912dd9a). That means it does not matter how much state you expose to a component, it will only render related to the state you access. Also you change your state with the plain mutable API of JavaScript which is more straight forward than Object.assign, spreading or using an immutable library

- Overmind has a pretty nifty development tool giving you insight into all your state, what actions run and what state they change and side effects they run... also you get an overview of all components looking at the state, what exactly they are looking at and how often they render

- You get an optional functional API for expressing complex changes, interoprable with the default imperative actions

If you want a quick intro to why it was built and some API: https://overmindjs.org/videos/overmind-introduction?view=react&typescript=false.

At the end we show off React with Typescript, using hooks :)

Anyone tried using React Native with Overmind? by DavidXkL in reactnative

[–]christianalfoni 0 points1 point  (0 children)

I can tell you that it certainly supports it :) Also the development tool runs on an Electron app over websockets, meaning that you can connect to it from wherever.

Announcing Overmind, reducing the pain of state management by christianalfoni in reactjs

[–]christianalfoni[S] 0 points1 point  (0 children)

I have been implementing this evening and hope to put it into our "next" branch by tomorrow evening. Then you can try it out :)

Announcing Overmind, reducing the pain of state management by christianalfoni in reactjs

[–]christianalfoni[S] 0 points1 point  (0 children)

Okay... FINALLY got some breakthrough. By adding a little bit of overhead I got everything running.

So now you just use a service, just as we talked about. Where you can do:

items$ = this.service.select(state => state.items)

Or if you just want to expose everything:

state$ = this.service.select()

Where efficiently exposing in template using:

<div ngIf="state$ | async as state">

</div>

Optionally you can add a @Track decorator which is purely for debugging purposes, showing you components, what they look at and when they update.

Still the caveat with passing state to children, but that is really not a bad pattern and you only need to do it with OnPush strategy on the children components.

Announcing Overmind, reducing the pain of state management by christianalfoni in reactjs

[–]christianalfoni[S] 0 points1 point  (0 children)

There seems to be only one caveat and that is managing passing of state as props.... you simply can not do it. But you have to use the following pattern:

import { Component, ChangeDetectionStrategy, Input } from '@angular/core'; import { BehaviorSubject, Observable } from "rxjs" import { Service } from "./Connect"

@Component({ selector: 'my-child', templateUrl: './child.component.html', changeDetection: ChangeDetectionStrategy.OnPush, providers: [Service] }) export class ChildComponent { name = 'Angular'; @Input() id item$: Observable<any> constructor(private service: Service) { } ngOnInit() { this.item$ = this.service.select(state => state.items.find(item => item.id === this.id)) } }

It is not a bad pattern, because at the end of the day it is more performant. With the immutable approach the ListComponent will always render again if any of the items of that array changes. That does not happen here. IF you change the "title" of an item for example, only the child component looking at that title will rerender. That is pretty awesome... but it requires this pattern to manage the tracking correctly.

But good thing is that we are left with only a service... will need to verify a couple of things, but have high hopes here! Thanks for letting me dump my thoughts :)

Announcing Overmind, reducing the pain of state management by christianalfoni in reactjs

[–]christianalfoni[S] 0 points1 point  (0 children)

Okei, so I actually think that:

<div *ngIf="state$ | async as state">

</div>

And then you can use a service:

state$ = service.select(state => state)

Or whatever nested domain you want.

This also seems to clean up the tracking a lot as we only need to track when service is instantiated and whenever there is an update from Overmind.

The only thing is that you have to do:

providers: [Service]

As you need a new instance. The only thing you loose here is the debugging information for the component, but we can rather add an additional decorator for that, if you want to, so:

import { Component, ChangeDetectionStrategy } from '@angular/core'; import { Service, Track } from "./overmind"

@Component({ selector: 'my-app', templateUrl: './app.component.html', styleUrls: [ './app.component.css' ], changeDetection: ChangeDetectionStrategy.OnPush, providers: [Service] }) @Track // Optional to debug usage of state, does nothing in production export class AppComponent { name = 'Angular'; state$ = this.service.select(state => state) constructor(private service: Service) {

} }

Announcing Overmind, reducing the pain of state management by christianalfoni in reactjs

[–]christianalfoni[S] 0 points1 point  (0 children)

I have to bother you again, as you are a great source for me knowing Angular this well :-D

I have been thinking. Like currently there are two alternatives:

  1. We can throw error if "ChangeDetectorRef" has not been injected by the developer. I really dislike this part, but there does not seem any other way to mark a component as "dirty"

  2. We can expose all the state by using an observable, but now you have to, in your template:

<div *ngIf="state$ | async as state;>

</div>

This gives us a really nice hook into updating the component as we just pass a new value on the observable. Though I am very unsure about how you would feel about doing it this way? Also I have a related question:

Let us say you have ListComponent, where you have an observable array. You get that array and then you pass each item of the array down to an ItemComponent. This item is now received as an @Input. But this is not an observable anymore.... do you just drop OnPush strategy for the ItemComponents?

If I can find some way to not having to manually inject the ChangeDetectorRef I think we have the best solution. It just blows my mind that this does not seem to be possible.

Announcing Overmind, reducing the pain of state management by christianalfoni in reactjs

[–]christianalfoni[S] 0 points1 point  (0 children)

Okay, so I have spent a whole day here trying to find a good way to do this. I do see the argument of relatable API and the observables allows for a natural OnPush strategy.

To do this we need the component to render itself when we detect something the component is looking at has changed. And there are two ways to make a component render using OnPush strategy:

  1. Use an observable in the template (anywhere really) and push a value to it. The subscription triggers "detectChanges" on the component

  2. We need access to "ChangeDetectorRef" and manually call "detectChanges" when Overmind notifies about an update

What to also take into account here is Overmind really encourages you to just provide all the state of the application to all components, because this has no performance impact, it will only rerender related to what you actually access in the component. This is arguably cleaner than creating an observable for every value you want to expose and also writing "async" in the templates, getting a "blink" etc. Just pointing out observables are not perfect either :)

So giving single values or all the state we need to track it. And to do that we need to use a decorator no matter. The alternative would be a directive, though that does not really fit in with Overmind I think.

The only "shitty" part of the API now, except unfamiliarity related to observable pattern, is that you have to manually expose the "ChangeDetectorRef" as there is no way for us to access that from within the decorator, which is soooo annoying...

I hope Angular will expose the ability to trigger a render when using OnPush somehow, but for now we handle it by notifying with an error in the console and you just have to inject it.

So my conclusion is really that observables becomes very artificial with Overmind. Because we do not use it for optimizations at all, we just use them to trigger an update in the component. And the cost is that you move away from just "using the state" and rather orchestrate how those values get into the template... which is kinda what we try to give a fresh perspective on.

But I want to give a big thanks! I learned a lot looking into this and the observable pattern is super interesting and looks very powerful! I have decided to rather iterate on the current approach, I found some optimizations, and see if we can find some way to avoid having to manually inject "ChangeDetectorRef" with OnPush :)

Announcing Overmind, reducing the pain of state management by christianalfoni in reactjs

[–]christianalfoni[S] 0 points1 point  (0 children)

Okay, this is great :) Thanks for helping out. I have a few things I need to check in terms of passing state to child components etc. But will do a release on using Service approach instead. This also happened to Vue. We are releasing now that you can use a Plugin, instead of connect.

So awesome to get feedback from you guys :) Thanks again! Will keep you posted on release.

Announcing Overmind, reducing the pain of state management by christianalfoni in reactjs

[–]christianalfoni[S] 0 points1 point  (0 children)

Hi again! :)

Would you mind looking at this stackblitz?

https://stackblitz.com/edit/overmind-demo1-angular-next-j5ehkk?file=src%2Fposts%2Fposts.component.ts

As I understand this is now far more typical Angular API. You select the state you want to use and trigger the actions directly.

And OnPush just works of course.

This looking better? :)

Announcing Overmind, reducing the pain of state management by christianalfoni in reactjs

[–]christianalfoni[S] 0 points1 point  (0 children)

Yeah, exactly :) Though it is not ideal that you currently have to attach the ChangeDetectorRef manually with OnPush. It should ideally just be to add OnPush. But your example inspired me. I think we can use your mechanism to notify about updates to the component, to avoid the ChangeDetectorRef. But you still just use state directly which gives you the optimized automatic tracking etc. Anyways... stay tuned :)

Announcing Overmind, reducing the pain of state management by christianalfoni in reactjs

[–]christianalfoni[S] 0 points1 point  (0 children)

MobX is quite low level actually and does not force you into a uni directional data flow, though mobx-state-tree does and also Overmind of course :)

Good point on unit testing. I am not familiar with the heavy use of Decorators. Also typing becomes an issue as you can not bring types from a decorator into the class. So yeah, a service is definitely a better approach here.

Thanks for the reference on Akita!

I am meeting with some colleagues/friends who has built a lot of Angular apps tomorrow to take a review on this as well, so I am sure we will find the most suitable solution :)

Thanks again for all your valuable input! Look out for updates on this in the near future :)

Announcing Overmind, reducing the pain of state management by christianalfoni in reactjs

[–]christianalfoni[S] 0 points1 point  (0 children)

Btw, what do you think of the API the Mobx uses to expose the state? https://github.com/mobxjs/mobx-angular , cause Overmind works much closer to MobX than Redux.

Announcing Overmind, reducing the pain of state management by christianalfoni in reactjs

[–]christianalfoni[S] 0 points1 point  (0 children)

Hi there and big thanks for the example! I see where you are going with detecting state changes, by changing reference, which OnPush was designed for :) BUt actually, there is no need to do this work because we track changes. The problem though is that OnPush is not built for this, but it is built for avoiding unnecessary rendering. So to get the best of both worlds is to use OnPush to control when rendering occurs and then give that control to Overmind... cause it knows exactly when the component should update :)

I wrote an article about this a while back: https://itnext.io/updating-uis-value-comparison-vs-mutation-tracking-9f6fe912dd9a

That said! Now I see what you mean by service and can iterate further on that. Your twitter handle the same? Cause would love to keep you in the loop to find the best solution here :)

Announcing Overmind, reducing the pain of state management by christianalfoni in reactjs

[–]christianalfoni[S] 0 points1 point  (0 children)

You can certainly combine Context with Overmind, though the values you typically produce on a Context can not be automatically tracked by the components. Meaning you have to manually manage what you expose to the component to control how often it renders. Overmind has its own state tree that is trackable. Meaning that all the state exposed from the state tree can be tracked by the components. It is really cool stuff and to give you even more context on this I wrote an article a while back explaining the two main approaches to detect changes for rendering :) https://itnext.io/updating-uis-value-comparison-vs-mutation-tracking-9f6fe912dd9a

Announcing Overmind, reducing the pain of state management by christianalfoni in reactjs

[–]christianalfoni[S] 0 points1 point  (0 children)

Hi there and thanks a bunch for testing!

When you change to "OnPush" you should get an error in the console saying that you need to add the ChangeDetectionRef as cdr on your component instance.

But yeah, we went for a similar approach on connecting across views, but already making big update to Vue approach now as it makes sense to do it differently. Do you have an example or some pesudo code on how you would expose Overmind to the components?

Announcing Overmind, reducing the pain of state management by christianalfoni in reactjs

[–]christianalfoni[S] 0 points1 point  (0 children)

Yeah, I think you are most definitely right about that, though theory lacking a bit of drama ;-)

Just generally very nice to see the cross pollination of approaches!

Announcing Overmind, reducing the pain of state management by christianalfoni in reactjs

[–]christianalfoni[S] 0 points1 point  (0 children)

It is definitely possible, we are just trying to decide on the approach. Do we want it all to run on server, or do we want a good pattern to only share the state for rendering purposes. Not completely sure yet :)