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
Page that depens on the state #773
Comments
Try getting/observing state in on mount maybe.
…Sent from my iPhone
On Sep 23, 2022, at 6:08 PM, isaribious ***@***.***> wrote:
Hi. I'm try to have a login feature in local go-app/docs. However, screen flickering may occurs when transition pages. Is there a way to avoid this?
As shown below, I use the state management to determine the login state. This code is based on this repo v9.6.4.
package main
func main() {
app.Route("/login", newLoginPage())
app.Route("/", newHomePage()) // Assume private page
app.Route("/getting-started", newGettingStartedPage()) // Assume public page
...
}
type homePage struct {
app.Compo
userID string
}
func newHomePage() *homePage {
return &homePage{}
}
func (p *homePage) OnNav(ctx app.Context) {
ctx.GetState("userid", &p.userID)
if p.userID == "" {
ctx.Navigate("/login")
return
}
}
type loginPage struct {
app.Compo
name string
password string
}
func newLoginPage() *loginPage {
return &loginPage{}
}
func (p *loginPage) login(ctx app.Context, event app.Event) {
if p.name != "hoge" || p.password != "foo" { // Quick check
return
}
ctx.SetState("userid", p.name,
app.Persist,
app.Encrypt,
app.ExpiresIn(time.Second*300),
)
ctx.Navigate("/")
}
When / page is accessed on the browser without being logged in, the client will redirect to /login page. However, the rendering of / page occurs at least once before it is navigated.
Is it inappropriate to expect that the queued UI goroutines will be canceled by executing Navigate()?
There are risks exposing content without user auth. So, I protect the content in Render().
func (p *homePage) Render() app.UI {
if p.userID == "" {
return app.A().
Href("/login").
Text("You are being navigated.")
}
return ... // Content that can be viewed after logging in.
}
After logged into / page, the screen flickers when transitioning from other page (ex. /getting-started). It also happens on reload of page. When the component was mounted, all member variables of the component are empty. I want to initialize a member with the state in OnInit(), but there is no way to do it.
If my approach is inappropriate, please correct it.
—
Reply to this email directly, view it on GitHub<#773>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/AAURM63GDKLJUTGHZPCTXDTV7VXQLANCNFSM6AAAAAAQTZG64M>.
You are receiving this because you are subscribed to this thread.Message ID: ***@***.***>
|
I know it is not very helpful, but those problems are why I do not use the original Go-App routing but my own "master component" that sits on "all routes" and manages the rest. I do not believe in having URLs available the user is not allowed to access in the first place. If I could not choose that, I would make the I don't think your problem is solvable without having the |
Thank you for your advice. I tried in |
@oderwat Thank you for your comment. For a route like |
@isaribious I created my mountpoint package to swap the component which is used in the page. My state/navigation changes this component as required. |
@oderwat I touched go-app-pkgs/examples/mountpoint/ and confirmed that there was no screen flickering due to page transitions. However, the flickering occurs when the page is reloaded. I changed the background color for clarity. func (c *isolate) Render() app.UI {
if c.Tabs == nil {
// return app.Div().Text("Unmounted")
return app.Div().Style("background-color", "cadetblue").Text("Unmounted") // Added style
}
return app.Div().Body(
app.A().Style("padding", "5px").Href("#0").Text("Tab 0"),
app.A().Style("padding", "5px").Href("#1").Text("Tab 1"),
app.A().Style("padding", "5px").Href("#2").Text("Tab 2"),
app.Div().Style("padding", "5px").Body(c.mp.UI()),
)
} |
@oderwat The mount package works fine if the member variables used to switch content are initialized in This is because a component is initialized before the first rendering is performed. Change Point:
However, in this issue, only this change doesn't effective because the component can't be initialized with a state. I won't disturb the go-app of design policy, but I tried the following change. Corrective Action Plan A:
package app
type Initializer interface {
Composer
// The function called before the component is pre-rendered or mounted.
- OnInit()
+ OnInit(Context)
}
func (c *Compo) mount(d Dispatcher) error {
if c.Mounted() {
return errors.New("mounting component failed").
Tag("reason", "already mounted").
Tag("name", c.name()).
Tag("kind", c.Kind())
}
if initializer, ok := c.self().(Initializer); ok && !d.isServerSide() {
- initializer.OnInit()
+ initializer.OnInit(d.Context())
}
c.disp = d
c.ctx, c.ctxCancel = context.WithCancel(context.Background())
root := c.render()
...
}
func (c *Compo) preRender(p Page) {
c.root.preRender(p)
if initializer, ok := c.self().(Initializer); ok {
- initializer.OnInit()
+ c.dispatch(initializer.OnInit)
}
if preRenderer, ok := c.self().(PreRenderer); ok {
c.dispatch(preRenderer.OnPreRender)
}
} package main
type homePage struct {
app.Compo
userID string
}
func (p *homePage) OnInit(ctx app.Context) {
ctx.GetState("userid", &p.userID)
} I made sure that the component be able to initialize with the state, and screen flickering have go away by this change. |
Besides, it is not me who decides anything about go-app: You could leave everything as is and make the user id a global variable. No need to use the state for that. Besides that, you can check in Render() if the component is mounted/initialized and skip rendering with some placeholder if it is not. I do this a lot. I also do not care about "reloading" a PWA. I avoid anything like that because it breaks everything you set up as an internal state for the app. It is like restarting your computer. The magic can work, but it needs a lot more than just knowing the URL in our cases. P.S.: Most of the time, I get the impression that people trying Go-App are using it for something that is merely a regular website with the declarative HTML appeal. I think of Go-App only in terms of SPA and would not load a big chunk of web assembly for a mundane HTML site I can do with any other web framework. |
Well I made go-app so search engines think it is normal webpage but @oderwat is totally right. It works as a SPA. |
@oderwat Thank you for your valuable opinion. I understand. I'll withdraw my proposal. In the first place, it may be wrong to try to do something like a redirect in the component. |
@maxence-charriere Do frequently mentioned murlok use the go-app's state? Is this site based on the idea of rendering some placeholder (which doesn't include user-specific content) without redirecting to another page if it's not authenticated? |
Murlok.io uses go-app states and change its content depending of if the user is logged in, without page redirection. |
@maxence-charriere Thank you so much for your reply. This time, I've come to the conclusion that placeholders in the component should not be used for the purpose of redirecting a page. |
Hi. I'm try to have a login feature in local go-app/docs. However, screen flickering may occurs when transition pages. Is there a way to avoid this?
As shown below, I use the state management to determine the login state. This code is based on this repo v9.6.4.
When
/
page is accessed on the browser without being logged in, the client will redirect to/login
page. However, the rendering of/
page occurs at least once before it is navigated.Is it inappropriate to expect that the queued UI goroutines will be canceled by executing
Navigate()
?There are risks exposing content without user auth. So, I protect the content in
Render()
.After logged into
/
page, the screen flickers when transitioning from other page (ex./getting-started
). It also happens on reload of page. When the component was mounted, all member variables of the component are empty. I want to initialize a member with the state inOnInit()
, but there is no way to do it.If my approach is inappropriate, please correct it.
The text was updated successfully, but these errors were encountered: