为什么parent组件中提交类型的按钮会触发OnInit

Why does button of type submit trigger OnInit in the parent component

有一个 parent 和一个 child 组件,child 有一个带有 2 个按钮的表单,一个是 submit 类型,另一个是 button。它们的 onclick 处理程序都调用 Actions 以便 parent 响应。 parent组件在处理了child发送的event后,submit按钮触发的事件也会触发parent上的OnInit ]. 为什么会这样?

示例:

Parent

<Child onsubmit=@((value)=>OnSubmit(value)) 
       oncancel=@((value)=>OnCancel(value))></Child>
@functions()
{ 
  private int x=3;
  protected override void OnInit()
  {
    Console.WriteLine($"From OnInit ,x={this.x}");
  }
  protected override void OnAfterRender()
  {
    Console.WriteLine($"From AfterRender,x={this.x}");
  }
  protected void OnSubmit(int _x) 
  { 
     //lets say child sends x=7
     this.x=_x;
     Console.WriteLine($"From handler, x={this.x}");
  }
  protected void OnCancel(int _x) 
  { 
     //lets say child sends x=7
     this.x=_x;
     Console.WriteLine($"From handler, x={this.x}");
  }
}

Child

   <form>
    <button type="submit" onclick="@(()=>OnPressSubmit())">Trigger submit</button>
     <button type="button" onclick="@(()=>OnPressCancel())">Trigger cancel</button> 
    <form>
    @functions()
    {
     [Parameter] protected Action<int> onsubmit{get;set;}
     public void OnPressSubmit()
     {
       this.onsubmit?.Invoke(7);
     }
     [Parameter] protected Action<int> oncancel{get;set;}
     public void OnPressCancel()
     {
       this.oncancel?.Invoke(7);
     }

当我 运行 这段代码时,在控制台中我会看到 variable 确实是在事件处理程序 OnEvent 中设置的,但是它随后在 OnInit.

OUTPUT(对于 submit 类型的按钮)

From Handler,  x=7  //in parent eventhandler
From OnInit, x=3
From OnAfterRender, x=3

OUTPUT(对于 button 类型的按钮)

From Handler,  x=7  //in parent eventhandler
From OnAfterRender, x=7

为什么 submit 按钮也会在 parent parent 处理事件后 OnInit 触发?

试试这个: 添加一个 StateHasChanged();方法如下:

protected void OnEvent(int _x) 
  { 
     //lets say child sends x=7
     this.x=_x;
     // If this works, then it is a bug with Blazor...
     // If not, be patient...
     StateHasChanged();

     Console.WriteLine($"From handler, x={this.x}");
  }

如果页面刷新,则输出是正确的:每当您重新加载页面时,就好像您是第一次 运行 一样。现在您应该找出页面刷新的原因。显示您的代码...

关于您的其他问题:在 Blazor 中重新渲染发生在状态因事件而改变的组件(StateHasChanged() 由 Blazor 隐式调用),或者当您显式调用 StateHasChanged() 方法时。重新渲染仅由受状态更改影响的组件完成,因此子组件可能会重新渲染,而其父组件不会。

编辑:根据您在下面所说的内容,我们现在知道重新加载页面的原因了, 因此,每次单击提交按钮时,x 的值为 3。 当然,当你点击另一个按钮时,父组件不会重新渲染,但正如我上面已经演示的,如果你在 OnEvent 方法中添加对 StateHasChanged() 的调用,父组件将重新渲染呈现,并且 x 变量将包含 7.

注意:您不应使用类型属性设置为 "submit" 的按钮。 Blazor 是一个 SPA 框架。不得通过提交表单(method="post")或设置按钮的type属性为"submit"来post表单数据。您应该改用 Ajax (HttpClient)。据我所知,Blazor 会阻止提交表单:也许只有带有 method="post" 和提交按钮的表单。

希望这对您有所帮助... 如果对您有帮助,请将我的回答标记为已接受