I have two Blazor custom components, Hello World 1, and Hello World 2, and a background UI timer on the razor page to hide and show components to demonstrate the proper use of StateChange and Invoke. However, the two components do not toggle the state in 3 seconds.
Index.razor
@page "/index"
<h3>Background Timer Example</h3>
@if (showComponent)
{
<div class="alert alert-success" role="alert">
This is a visible component!
</div>
}
<HelloWorld1 @ref="helloWorld1" />
<HelloWorld2 @ref="helloWorld2" />
<button class="btn btn-primary" @onclick="ToggleComponent">Toggle Component</button>
@code {
private bool showComponent = true;
private bool showHelloWorld1 = true;
private bool showHelloWorld2 = true;
private HelloWorld1 helloWorld1;
private HelloWorld2 helloWorld2;
// Timer interval in milliseconds
private const int TimerInterval = 3000;
private System.Threading.Timer timer;
protected override void OnInitialized()
{
// Initialize the timer when the component is first initialized
timer = new System.Threading.Timer(ToggleComponentVisibility, null, TimerInterval, TimerInterval);
}
private async void ToggleComponentVisibility(object state)
{
// Toggle the visibility of the component
showComponent = !showComponent;
// Toggle the visibility of HelloWorld1 component
showHelloWorld1 = !showComponent;
// Toggle the visibility of HelloWorld2 component
showHelloWorld2 = !showComponent;
// Notify the framework that the state has changed
await InvokeAsync(() => StateHasChanged());
}
private async Task ToggleComponent()
{
// Toggle the visibility of the component
showComponent = !showComponent;
showHelloWorld1 = !showComponent;
showHelloWorld2 = !showComponent;
// Notify the framework that the state has changed
// Note: Use InvokeAsync for thread safety
await InvokeAsync(() => StateHasChanged());
}
// Dispose the timer when the component is disposed
public void Dispose()
{
timer.Dispose();
}
}
HelloWorld1.razor
<h4>Hello from HelloWorld1!</h4>
@if (!showHelloWorld1)
{
<p>Hidden!</p>
}
else
{
<p>Visible!</p>
}
@code {
[Parameter]
public bool showHelloWorld1 { get; set; }
}
HelloWorld2.razor
<h4>Hello from HelloWorld2!</h4>
@if (!showHelloWorld2)
{
<p>Hidden!</p>
}
else
{
<p>Visible!</p>
}
@code {
[Parameter]
public bool showHelloWorld2 { get; set; }
}
You've only added @ref to reference the child component instance, but haven't pass the value. Add
showHelloWorld1="showHelloWorld1"
to pass it.Meanwhile, the value-changing order of
showComponent
needs modifying since changing first will cause the two child components value to be wrong.Index.razor