Pavan Sista
Pavan Sista

Reputation: 92

Blazor StateHasChanged doesnt reset the component to its initial state

I am using Blazor Server Pages. I need to reset to initial state of my component onClick. I am using StateHasChanged() which is called on clicking the update button but does not reset the input field to the initial Value. My Component is given below.

@using DataAcessLibrary;
@using TableMaintenance.Models
@using TableMaintenance.Data;

@if (dr != null)
{
    int count = 0;
<tr>

    <td style="padding:0px"><button type="button" class="btn btn-link btn-sm" style="padding:0px" @onclick="@DeleteRow"><img src="/images/x-square.svg" /></button></td>
    @foreach (var item in dr.ItemArray.Where((a, b) => ColDisplayIndex.Contains(b)))
    {
        string id = ColumnsList[ColDisplayIndex[count++]].ToString();
      
        <td style="padding:0px;">
            <DataRowInput Id="@id" Input=@(item.ToString()) OnChangeDropDown="@AddDropDownValue" OnChangeInput="@AddInputValue" />
        </td>
        <td>
            <input type="text" />
        </td>
    }
<td  style="padding:0px">
    <button style="padding:3px;margin:0px" type="button" class="btn btn-light btn-sm" @onclick="@UpdateRow">update</button>
</td>
</tr>
}

My main goal is to reset DataRowInput to its initial state on clicking update button. I used input field for testing purpose and it does not reset too ( the input that I typed stays there even after clicking the update button). I am new to Blazor and only way I could find to re-render a component is via StateHasChanged. But this is not resetting values to their Initial state. The update method is given below

public void UpdateRow()
{
StateHasChanged();
}

Is this possible with StateHasChanged() or is there any other way?

Upvotes: 0

Views: 2099

Answers (1)

F0urL1ghts
F0urL1ghts

Reputation: 105

Unless I'm missing something, your Update() function isn't doing anything but calling StateHasChanged().

I think you could be misunderstanding how "re-rendering" works in Blazor. It doesn't try to re-render the component from the original state. It's a function that lets Blazor know that something should have changed visually.

In most cases, this should happen automatically without you having to specifically call StateHasChanged().

To do what you're trying to do, you could have the input bind to a string and then have the update function reset that to a default value. It would look something like this:
(Please note that I did not double check the syntax. This is an example.)

<input @bind="myString" />
<button @onclick="resetMyString">Reset</button>
@code{
    private string myString {get; set;}
    private void resetMyString(){
        myString = "";
    }
}

EDIT:
I do see now that you're trying to do this on a list of objects. This is a bit different especially depending on the data you're working with.

If you're working with a list of primitives, please look at this stack overflow answer. He summarizes "binding" to a list of objects better than I can. https://stackoverflow.com/a/61485002/11991272

If you're working with a list of non-primitives, I think you can bind to the individual properties without having to use @onchange to update the elements in the list.

EDIT 2 (working implementation using the above mentioned answer):

    <button @onclick="addToList">Add To List</button>
    <br />
    @for (int i = 0; i < myList.Count; i++)
    {
        var index = i;
        <div>
            <input type="text" value="@myList[index]" @onchange="(e => myList[index] = e.Value.ToString())" />
            <button @onclick="() => resetRow(index)">Reset</button>
        </div>
    }
    <br />
    <button @onclick="removeLastItem">Remove Last Item</button>

@code {
    private List<string> myList = new() { "one", "two", "three", "four", "five" };
    private void resetRow(int i)
    {
        myList[i] = "";
    }
    private void addToList()
    {
        myList.Add("");
    }
    private void removeLastItem()
    {
        if (myList.Count > 0)
            myList.RemoveAt(myList.Count - 1);
    }
}

Upvotes: 2

Related Questions