Hello,
Framework is missing feature to pass component to another component as parameter.
If I have one parent component and to child components and I want to call parent with selected child component I can't do now.
For example we have modal form and want to display different components inside modal component, e.g. message, error, confirm and etc.
If it is possible please provide minimal sample or consider to add this basic feature to framework.
Thank you.
This is because setting parameters happens before rendering, and child components do not exist until after the parent has rendered.
Try making you parameter type Func <T> instead of T. As long as you only access it after a Render (eg user clicks something).
However, having said that, it's still better to have your child components expose an EventCallback<T> that the parent subscribes to that is triggered by the child when selected.
@Lupusa87 thanks for contacting us.
@mrpmorris answer is correct. You can't get a hold to child components until the app has rendered and it is best if you use an EventCallback to notify the parent and do something with the component.
I see I did not expained well.
I am talking about taking whole component and passing it as parameter to another component.
Let's imagine modal component which is displaying in one case one component and in another case another component.
I do not talk about renderfragment or anything else.
I need component wrapper.
There should be way to render component inside another component through setting parameter.
It should be easy, parent component receiving another component as parameter will add it to rendertree.
@javiercn @SteveSandersonMS @danroth27
@Lupusa87 thanks for the additional details.
If you are asking about "holding on" to a "component instance", passing that as a parameter to some other component, and "somehow" inside that component, having it render the "component instance" passed as a parameter, that's not something we support and it's not something we'll ever support.
In the Blazor model, the framework is in charge of the lifetime of the component, what you propose would break the Blazor rendering model in a very bad way.
The best you can do is pass the component type to your modal as T and pass in any additional parameter to the T component instance.
@Lupusa87 I think I understand what you're asking for. It sounds like you want to instantiate your own component objects and then render them.
If that's the case, this is deliberately not how the rendering system works (not only in Blazor, but also in other diff-based frameworks like React). When a component renders, it provides a description of the other components it wants to render inside itself, not the actual component instances themselves. This is how we can be sure that the framework is responsible for the whole lifecycle of components: it chooses when to create them, when lifecycle events like dependency injection and OnInitialized etc fire, when to reuse them, and when ultimately to destroy them. It's also how we can guarantee that component instances are only used in one place. If the rendering system accepted existing component instances, it would not be in control over their lifecycle.
So, instead of thinking about passing component instances around, you should think at one further level of abstraction and pass around descriptors of what you want. This can be either:
RenderFragment is. This is basically why RenderFragment exists as a concept.I know there might be cases where it feels like it would be convenient to "new" up a component instance but it would complicate so many other aspects of the rendering pipeline and prevent us from offering the safety guarantees we do offer today. And again for clarification, this is not a unique thing about Blazor - the same applies in React too, for example.
As far as I'm aware there shouldn't be any scenarios blocked by this, because RenderFragment provides what you need. But if you're unsure how to implement a particular thing please let us know :)
@javiercn Ah, looks like we answered at the same time. Glad our answers were consistent!
Thank you, RenderFragment seems to solve my issue.