为什么当我从列表中删除绑定到组件的项目时,它从列表中删除了正确的项目但复制了最后一个项目

Why when I delete item from list binds to component, it deletes the right item from the list but duplicated the last item

我在 Blazor 服务器应用程序中有一个奇怪的行为。

当我有一个对象列表并删除列表中的一个项目时,它会删除列表中的正确项目,但它会将最后一项的数据复制到它之前的项目。

只有当我将列表数据绑定到我自己的组件时才会发生。 如果我将它直接绑定到输入元素,它就不会发生。

我在下面的小代码示例中重现了该行为,只需尝试删除第二项并查看该行为。

感谢谁能提供帮助...

Blazor 标记

 <table>
    <thead>
        <tr>
            <th>Id</th>
            <th>Name</th>
            <th></th>
        </tr>
    </thead>
    <tbody>
        @foreach (User user in _users)
        {
            <tr>
                <td><MyText @bind-Value="user.Id"></MyText></td>
                <td><MyText @bind-Value="user.Name"></MyText></td>
                <td @onclick="(() => DeleteUser(user))">delete</td>
            </tr>
        }
    </tbody>
</table>

Blazor 代码

private List<User> _users = new List<User>();
private class User
{
    public string Id { get; set; } = "";
    public string Name { get; set; } = "";
}

protected override void OnInitialized()
{
    _users.Add(new User() { Id = "1", Name = "Adam" });
    _users.Add(new User() { Id = "2", Name = "Benny" });
    _users.Add(new User() { Id = "3", Name = "Charles" });
    _users.Add(new User() { Id = "4", Name = "David" });
    base.OnInitialized();
}

private void DeleteUser(User user)
{
    _users.Remove(user);
}

MyText 组件

<input @bind-value="@Value" />

@code {

    public string _value = "";

    [Parameter]
    public EventCallback<string> ValueChanged { get; set; }

    [Parameter]
    public string Value
    {
        get
        {
            return _value;
        }
        set
        {
            if (_value != value)
            {
                _value = value;
                ValueChanged.InvokeAsync(value);
            }
        }
    }    
}

Blazor 的 'diffing engine' 你得帮点忙。像这样使用 @key


@foreach (User user in _users)
{
    <tr @key="user">
        <td><MyText @bind-Value="user.Id"></MyText></td>
        <td><MyText @bind-Value="user.Name"></MyText></td>
        <td @onclick="(() => DeleteUser(user))">delete</td>
    </tr>
}