You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SSR父组件向InteractiveServer子组件传递EventCallback为空问题求助

问题解决方法

你的问题核心是SSR(静态服务器渲染)父组件与InteractiveServer交互式子组件处于不同渲染上下文,导致EventCallback无法跨上下文触发父组件方法。以下是几种可行的解决思路:

方法一:使用共享状态服务传递数据

通过注入全局共享的状态服务,让子组件触发状态变更,父组件订阅该变更来获取数据。

1. 创建共享状态服务

public class NameStateService
{
    // 定义事件用于传递数据
    public event Action<string> NameEntered;

    // 子组件调用此方法触发事件
    public void TriggerNameEntered(string name)
    {
        NameEntered?.Invoke(name);
    }
}

2. 注册服务(Program.cs)

builder.Services.AddScoped<NameStateService>();

3. 修改父组件(Parent.razor)

@inject NameStateService NameState
@implements IDisposable

<Child @rendermode="InteractiveServer" />

@code {
    protected override void OnInitialized()
    {
        // 订阅子组件触发的事件
        NameState.NameEntered += DisplayName;
    }

    public void DisplayName(string result)
    {
        Console.WriteLine($"Result is {result}");
    }

    public void Dispose()
    {
        // 取消订阅避免内存泄漏
        NameState.NameEntered -= DisplayName;
    }
}

4. 修改子组件(Child.razor)

@inject NameStateService NameState

<input @bind="name"/>
<button type="button" @onclick="NameEntered">Click</button>

@code {
    private string name;
 
    public async Task NameEntered()
    {
        // 触发状态服务的事件传递数据
        NameState.TriggerNameEntered(name);
    }
}

方法二:将父组件改为交互式渲染(如果允许)

如果父组件不需要严格保持SSR,可以将其也设置为InteractiveServer渲染模式,这样父子组件处于同一上下文,EventCallback就能正常工作:

修改父组件(Parent.razor)

@rendermode="InteractiveServer"

<Child OnNameEntered="@DisplayName"/>

@code {
    public void DisplayName(string result)
    {
        Console.WriteLine($"Result is {result}");
    }
}

子组件无需单独设置rendermode,会继承父组件的渲染模式。

方法三:使用JavaScript互操作传递数据

通过JS桥接,让子组件调用JS方法,再由JS触发父组件的.NET方法:

1. 父组件注册JS回调(Parent.razor)

<Child @rendermode="InteractiveServer" />

<script>
    window.receiveNameFromChild = (name) => {
        // 调用父组件的.NET方法,替换为你的项目程序集名称
        DotNet.invokeMethodAsync('YourAssemblyName', 'DisplayName', name);
    };
</script>

@code {
    [JSInvokable]
    public static void DisplayName(string result)
    {
        Console.WriteLine($"Result is {result}");
    }
}

2. 修改子组件(Child.razor)

@inject IJSRuntime JSRuntime

<input @bind="name"/>
<button type="button" @onclick="NameEntered">Click</button>

@code {
    private string name;
 
    public async Task NameEntered()
    {
        // 调用JS方法传递数据
        await JSRuntime.InvokeVoidAsync("receiveNameFromChild", name);
    }
}

方法四:使用表单提交(适合表单场景)

如果子组件是表单的一部分,可以通过表单提交将数据传递给父组件:

修改子组件(Child.razor)

@inject NavigationManager NavigationManager

<form @onsubmit="HandleSubmit">
    <input @bind="name"/>
    <button type="submit">Click</button>
</form>

@code {
    private string name;
 
    private async Task HandleSubmit()
    {
        // 通过查询参数传递数据到父组件页面
        await NavigationManager.NavigateTo($"/parent?name={Uri.EscapeDataString(name)}");
    }
}

父组件可通过查询参数解析获取数据,适合不需要实时交互的场景。


内容的提问来源于stack exchange,提问作者bisoy27

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 14:02:40