go-app
go-app copied to clipboard
I still don't get the point about exported / state / attrribute
Hi Maxence, All my best for this new year. Thank you for your work... Anytime I'm about to write some js, I go back to go-app...
Thought I got the trick until I move to go-app v9. My component isn't updated anymore. This breaks again my fragile understanding of the update logic.
I have read again the page https://go-app.dev/components#exported-vs-unexported. I have also read #605 and my one #530
First, the update logic has changed somehow with V9. I wrote a piece of code to illustrate the point https://github.com/simulot/go-app-example .
There are 2 versions of the component. One with the current selection held into an non exported field, the other using an exported field.
With go-app v8, both version of the component behave as I'm expecting: the clicked option is highlighted.

With go-app v9, only the non exported field version behaves as I'm expecting:

In both cases, the component representation in HTML is identical. So I think this come from misunderstanding of the update logic.
Why the "exportable" property of the field matters? When this is used in the update loop? I'm surprised that the change of a non exported field triggers the update. How the change is detected then? Maybe the update is triggered based on effecting rendering (i mean the app.UI structure)? Maybe, the exportable state matters only for embedded components.
Could you clarify the point? I'm thinking about writing the common example of todo app to illustrate many concepts.
Use exported when you want to have a field to be set by a parent component.
If you modify a exported field following a js event like a click, a render will be triggered, creating a new version of the tree with the value set by the parent. Your modification is then overridden by the parent value.
Unexported fields are not compared with the ones from the new version of the tree. You can use them to store data, there will not be overriden.
Translated from the js frameworks - Exported fields = state, unexported fields = props
Translated from the js frameworks - Exported fields = state, unexported fields = props
js frameworks are foreign to me. I try to avoid js using go.
If you modify a exported field following a js event like a click, a render will be triggered, creating a new version of the tree with the value set by the parent. Your modification is then overridden by the parent value.
@maxence-charriere , so what's the point of having an exported field that is overridden by the parent when the component is updated?
@simulot If you need to pass state between components use exported fields. If the value is local to the component and not used elsewhere use unexported.
@mar1n3r0, it doesn't help when the field is restored with the initial value. The idea with menu use was to inform the application when the user select an option, and keep the menu state updated when the user is going back or so. Ideally the menu is located into its own package. I have used an action with success for the menus.
I'm still thinking this system is a kind of black box which is difficult understand.
To be frank I am also a bit confused by the recent changes. Namely: https://go-app.dev/components#exported-vs-unexported and https://go-app.dev/states.
Back in the early days I used exported fields as app state, unexported fields as component properties and local storage for anything that should survive a reload.
If you modify a exported field following a js event like a click, a render will be triggered, creating a new version of the tree with the value set by the parent. Your modification is then overridden by the parent value.
Surely this gets me confused as well. If this is meant to maintain parent-child relations then the relevant question is probably how do we change parent state?
Another question would be is there a way to propagate a state change from child to parent.
A component is a customizable, independent, and reusable UI element that allows your UI to be split into independent and reusable pieces.
Also how do we share and update state between independent non-hierarchical components? Say for example we have a home component and a separate gallery component. Both of them fetch the same data independently and are supposed to update the other component with the newest version.
I haven't personally researched the implementations of all new logic in v9 so it's relevant to me as well. Hope @maxence-charriere can help us clarify these.
This is how I understand it:
Exported field = Anything you set from outside (but don't change it inside, ever!) by setting a new component "over" the still mounted one.
Unexported field = Keep track of the state inside this component (while it is still mounted).
Sync a value (state) in different components = SetState/ObserveState. Handle complex actions between components = Handle/NewAction(WithValue).
The way Go-App works is that if you render a component "the first time" it is getting mounted. If you render it again (using a new or old version of the component data structure aka 'same type') it updates the component (and only the exported values) with new values from the new component while maintaining the state of the "original" (first mounted) data.
Basically, every component gets just updated after it was first mounted. This is also the reason, why you can't "swap" two components as it will only update the exported fields but not the unexported ones in this case.