スキル一覧に戻る
barracoder

blazor-components

by barracoder

0🍴 0📅 2026年1月25日
GitHubで見るManusで実行

SKILL.md


name: blazor-components description: Blazor-specific patterns for components, JS interop, and state management

blazor-components

Patterns for building Blazor WebAssembly components effectively.

JS Interop

Invoking JavaScript from C#:

await JSRuntime.InvokeVoidAsync("functionName", arg1, arg2);
var result = await JSRuntime.InvokeAsync<string>("functionName", arg1);

Receiving calls from JavaScript:

private DotNetObjectReference<MyComponent>? _dotNetRef;

protected override void OnInitialized()
{
    _dotNetRef = DotNetObjectReference.Create(this);
}

[JSInvokable]
public void OnJsCallback(string data)
{
    // Handle callback from JS
    StateHasChanged();
}

Disposal Pattern

Always implement IAsyncDisposable for JS interop components:

@implements IAsyncDisposable

@code {
    private DotNetObjectReference<GameCanvas>? _dotNetRef;

    public async ValueTask DisposeAsync()
    {
        if (_dotNetRef is not null)
        {
            await JSRuntime.InvokeVoidAsync("cleanup", _dotNetRef);
            _dotNetRef.Dispose();
        }
    }
}

State Management

UI updates after async/JS operations:

// From JS callback or async operation - must use InvokeAsync
await InvokeAsync(StateHasChanged);

// From synchronous event handler - direct call is fine
StateHasChanged();

Shared state via DI service:

// Services/GameState.cs
public class GameState
{
    public int Score { get; set; }
    public int Lives { get; set; }
    public event Action? OnChange;
    public void NotifyStateChanged() => OnChange?.Invoke();
}

// Program.cs
builder.Services.AddSingleton<GameState>();

// Component
@inject GameState State
@implements IDisposable

protected override void OnInitialized() => State.OnChange += StateHasChanged;
public void Dispose() => State.OnChange -= StateHasChanged;

Canvas Rendering

Use Blazor.Extensions.Canvas for 2D graphics:

@using Blazor.Extensions
@using Blazor.Extensions.Canvas.Canvas2D

<BECanvas Width="800" Height="600" @ref="_canvasRef" />

@code {
    private BECanvasComponent? _canvasRef;
    private Canvas2DContext? _context;

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            _context = await _canvasRef!.CreateCanvas2DAsync();
        }
    }

    private async Task Render()
    {
        await _context!.ClearRectAsync(0, 0, 800, 600);
        await _context.SetFillStyleAsync("green");
        await _context.FillRectAsync(x, y, width, height);
    }
}

Collision Detection

Axis-aligned bounding box (AABB) helper:

private static bool RectsIntersect(
    double x1, double y1, double w1, double h1,
    double x2, double y2, double w2, double h2)
{
    return x1 < x2 + w2 && x1 + w1 > x2 &&
           y1 < y2 + h2 && y1 + h1 > y2;
}

Game Loop Pattern

requestAnimationFrame via JS interop:

// wwwroot/js/gameLoop.js
let animationId = null;

window.startGameLoop = (dotNetRef) => {
  const loop = (timestamp) => {
    dotNetRef.invokeMethodAsync("OnFrame", timestamp);
    animationId = requestAnimationFrame(loop);
  };
  animationId = requestAnimationFrame(loop);
};

window.stopGameLoop = () => {
  if (animationId) cancelAnimationFrame(animationId);
};
[JSInvokable]
public async Task OnFrame(double timestamp)
{
    Update();
    await Render();
    await InvokeAsync(StateHasChanged); // Sync Blazor UI
}

Common Gotchas

  • Call InvokeAsync(StateHasChanged) after canvas Render operations to sync Blazor markup
  • Blazor WASM is single-threaded—avoid blocking calls
  • Use @key directive when rendering lists that change order
  • JS files must be in wwwroot/ and referenced in index.html
  • OnAfterRenderAsync(firstRender: true) is when DOM/canvas is ready

スコア

総合スコア

50/100

リポジトリの品質指標に基づく評価

SKILL.md

SKILL.mdファイルが含まれている

+20
LICENSE

ライセンスが設定されている

0/10
説明文

100文字以上の説明がある

0/10
人気

GitHub Stars 100以上

0/15
最近の活動

3ヶ月以内に更新がある

0/10
フォーク

10回以上フォークされている

0/5
Issue管理

オープンIssueが50未満

+5
言語

プログラミング言語が設定されている

+5
タグ

1つ以上のタグが設定されている

0/5

レビュー

💬

レビュー機能は近日公開予定です