Closed crimer closed 1 year ago
Hi, I see a few errors in your code, you're mixing imperative and declarative approaches. Try to always to declare what should be your view based on the state. As a general rule, State is owned by the parent component and passed to the child as props. Another thing you should always avoid is taking references to visual node elements like a component because they are replaced every time the render tree is recreated. This is something you should write instead
public enum PageState
{
Success = 0,
Error = 1,
Loading = 2
}
public class FirstPageState
{
public PageState PageState { get; set; }
}
public class FirstPage : Component<FirstPageState>
{
public override VisualNode Render()
=> new BasePage()
{
new VStack()
{
new Label("First!"),
new Button("Change view")
.OnClicked(() =>
{
SetState(s => s.PageState = PageState.Loading);
Task.Run(async () =>
{
await Task.Delay(TimeSpan.FromSeconds(2));
SetState(s => s.PageState = PageState.Success);
});
})
}
.Spacing(20)
.HCenter()
.VCenter()
}
.IsLoading(State.PageState == PageState.Loading)
.IsError(State.PageState == PageState.Error)
;
}
public class BasePage : Component
{
private bool _isLoading;
private bool _isError;
public BasePage IsLoading(bool isLoading)
{
_isLoading = isLoading;
return this;
}
public BasePage IsError(bool isError)
{
_isError = isError;
return this;
}
public override VisualNode Render()
{
return new ContentPage()
{
_isLoading ? new Label("Loading view") : null,
_isError ? new Label("Error view") : null,
!_isLoading && !_isError ? Children() : null,
}.Title("Base");
}
}
public class App : Component
{
public override VisualNode Render()
{
return new NavigationPage()
{
new FirstPage()
}.Set(Microsoft.Maui.Controls.NavigationPage.BarTextColorProperty, Colors.White);
}
}
Thanks for help. My experience using React JS made me make some kind of the Context. MauiReactor has a CreateParameter
Well, yes, the Parameters feature (https://adospace.gitbook.io/mauireactor/components/component-parameters) is something similar (actually inspired to) ReactJs context but it's not of course a global state manager like Redux etc. KeeMind sample https://github.com/adospace/kee-mind uses the parameters approach.
One other option is to use dependency injection and inject your global state into your components. You could subscribe/unsubscribe to state-changed events when required through the combination OnMount/OnPropsChange/OnWillUnmount.
In my applications I usually start using the normal way to pass state to children using props, moving to other approaches when I saw the real benefit but of course, it's just a matter of choice.
Okay, I got it, I'll look at your example, thank you
Hi, I have a page that can change its own state. Below is an example. When I click the button, the state changes to the "Loading state" and then it automatically change back, but Children are not displayed.