Your code does not work simply because it lacks a call to the StateHasChanged method:
EditButton.razor
<button class="btn btn-outline-primary" @onclick="OnClick"> @ButtonText</button>
@code {
[Parameter]
public string ButtonText { get; set; } = "Edit";
public void OnClick()
{
ButtonText = ButtonText == "Edit" ? "Editing..." : "Edit";
InvokeAsync(() => StateHasChanged());
}
}
Note That I added a call to the StateHasChanged method to re-render the component after its state has changed.
InvokeAsync(() => StateHasChanged());
Index.razor
@page "/"
<EditButton @ref="EditButton"></EditButton>
<button class="btn-primary" @onclick="ChangeButtonText">Change Button Text</button>
@code {
EditButton EditButton;
void ChangeButtonText()
{
EditButton.OnClick();
}
}
To sum up: What you do is fine, but you must call the StateHasChaged method manually. It is not called automatically by the framework. Note that it is not necessary to add a call to the StateHasChaged method from event handler that handle UI event, such as the 'click' event. But in your case it is necessary, as the EditButton.OnClick event handler is not a UI event handler. That was the only issue with your code.
IMPORTANT: You should not modify or change the state of a Component parameter property. This should be avoided:
[Parameter]
public string ButtonText { get; set; } = "Edit";
As well as this:
ButtonText = ButtonText == "Edit" ? "Editing..." : "Edit";
Component parameter properties should be automatic properties:
[Parameter]
public string ButtonText { get; set; }
And they must never be modified outside of the component. Read this Read this. Instead you should define local variable or properties that are assigned from the component parameter properties' values, on which you can apply whatever manipulations you want.
Not adhering to that rule may result in unfavorable side effects in large components, only Steve Sanderson can discern.