SlideShare uma empresa Scribd logo
1 de 13
PRACTICAL BLAZOR
for Minnesota Developers Conference 2022
Patrick Szalapski
Applications Architect, General Mills
@Szalapski | szalapski.com
AGENDA
1. Cross-cutting concerns, such as profiling,
using abstract components
2. Speeding up rendering with virtualization
3. Avoiding rerendering with abstract
components
4. Breaking a Blazor component into
subcomponents
DEMO
• Ask me (now or afterward) about:
• Mechanical keyboards
• New File extension
• Windows Terminal
• Nullable and non-nullable references
• Unhelpful VSPro removes “watch”
• VS Intellisense slightly broken for Blazor
• Refactor one step at a time, even if confident
• Agile, Scrum, Kanban, team concerns
This is
Minnesota Developers Conference,
not
Minnesota Managers Conference:
Let’s code, not read slides
Tangents we might hit…
 dotnet watch vs. VS run
 speed up your development loop
 Blazor favicon animated glyph
 `null!` convention for required parameters
MAKING A SUBCOMPONENT IN BLAZOR
1.Insert (non-working) markup calling the new
subcomponent above old markup
2.Copy the entire component as new component
3.Delete unnecessary markup and code in subcomponent
4.Add parameters
5.Add “…Changed” EventCallback parameters
6.Test and fix as doubled-up behavior
7.In the parent, delete the doubled-up markup, code,
directives
MAKING A SUBCOMPONENT IN BLAZOR
(ELABORATED)
1. Insert markup for the new subcomponent usage (above the markup
that will be removed).
2. Copy the entire component to a new file. Rename it to match the
above.
3. Edit the new subcomponent to delete all markup that should remain
in the parent only. Delete all code that is thus unused.
4. Add parameters for missing references; supply them in the parent.
5. Add “…Changed” EventCallback parameters for anything editable.
6. Now you have a subcomponent that works and a parent that also
works with its markup repeated (doubled up). Test and fix anything
that is broken.
7. In the parent, delete the appropriate markup, code, and directives.
BINDING REFERENCE
<select value="Bob" /> a literal string “Bob“, obviously
<select value="@myName" /> one-way binding: the rendered option always gets the updated value of myName
<select @value="myName" /> AVOID - error: '@value' is not a valid attribute name.
<select @value="@myName" /> AVOID - error: '@value' is not a valid attribute name.
<select value="@myName“
@onchange="handleChange" />
one-way binding with event on change, a good approach when custom logic is needed
(e.g saving to a web API then conditionally updating the value); note, handleChange is a
reference to a function that takes one parameger, a ChangeEventArgs instance.
<select @bind="@myName" /> Two-way binding using the special value attribute and onchange event; same as
<select value="@myName" onchange="e => myName = e.Value" />
<select @bind-Item="myName" />
(or any attribute, not just "value")
Two-way binding; same as
<select Item="@myName" ItemChanged="e => myName = e.Value" />
<select @bind-Item="myName"
@bind-Item:event="oninput" />
Two-way binding using custom event; same as
<select Item="@myName" @oninput="e => myName = e.Value" />
<MyComponent MyParameter1="@("firstName")" /> (Custom component) Literal string
<MyComponent MyParameter1="firstName" /> NOT a literal string; passes the value of firstName as a one-way binding
<MyComponent MyParameter1="@firstName" /> AVOID - redundant
<MyComponent @MyParameter1="…" /> AVOID - ERROR - bad syntax
<MyComponent @bind-MyParameter1="…" /> Two-way binding; same as
<MyComponent MyParameter1="myName" MyParameter1Changed="e => myName =
e.Value" />
(both the MyParameter1 parameter and the MyParameter1Changed event must
STRETCH GOAL: UNPREPARED BLAZOR CHAT
• Get-only properties are better than mutating state
• CallbackEvents can be bound to either synchronous or async methods
• OnParametersSetAsync and OnAfterRender are the two methods you have to react
to in a subcomponent

Mais conteúdo relacionado

Semelhante a MDC 2022 Practical Blazor.pptx

AEM Sightly Deep Dive
AEM Sightly Deep DiveAEM Sightly Deep Dive
AEM Sightly Deep DiveGabriel Walt
 
Toms introtospring mvc
Toms introtospring mvcToms introtospring mvc
Toms introtospring mvcGuo Albert
 
JavaScript Framework Smackdown
JavaScript Framework SmackdownJavaScript Framework Smackdown
JavaScript Framework Smackdownmeghantaylor
 
From Backbone to Ember and Back(bone) Again
From Backbone to Ember and Back(bone) AgainFrom Backbone to Ember and Back(bone) Again
From Backbone to Ember and Back(bone) Againjonknapp
 
Novedades de MongoDB 3.6
Novedades de MongoDB 3.6Novedades de MongoDB 3.6
Novedades de MongoDB 3.6MongoDB
 
Fly High With Angular - How to build an app using Angular
Fly High With Angular - How to build an app using AngularFly High With Angular - How to build an app using Angular
Fly High With Angular - How to build an app using AngularVacation Labs
 
Spring MVC Intro / Gore - Nov NHJUG
Spring MVC Intro / Gore - Nov NHJUGSpring MVC Intro / Gore - Nov NHJUG
Spring MVC Intro / Gore - Nov NHJUGTed Pennings
 
Design Patterns in ZK: Java MVVM as Model-View-Binder
Design Patterns in ZK: Java MVVM as Model-View-BinderDesign Patterns in ZK: Java MVVM as Model-View-Binder
Design Patterns in ZK: Java MVVM as Model-View-BinderSimon Massey
 
CTTDNUG ASP.NET MVC
CTTDNUG ASP.NET MVCCTTDNUG ASP.NET MVC
CTTDNUG ASP.NET MVCBarry Gervin
 
AngularJS Beginner Day One
AngularJS Beginner Day OneAngularJS Beginner Day One
AngularJS Beginner Day OneTroy Miles
 
Asp.net mvc training
Asp.net mvc trainingAsp.net mvc training
Asp.net mvc trainingicubesystem
 
KnockOutjs from Scratch
KnockOutjs from ScratchKnockOutjs from Scratch
KnockOutjs from ScratchUdaya Kumar
 
Beginning AngularJS
Beginning AngularJSBeginning AngularJS
Beginning AngularJSTroy Miles
 
PyData Berlin 2023 - Mythical ML Pipeline.pdf
PyData Berlin 2023 - Mythical ML Pipeline.pdfPyData Berlin 2023 - Mythical ML Pipeline.pdf
PyData Berlin 2023 - Mythical ML Pipeline.pdfJim Dowling
 
Spring framework in depth
Spring framework in depthSpring framework in depth
Spring framework in depthVinay Kumar
 
angularJs Workshop
angularJs WorkshopangularJs Workshop
angularJs WorkshopRan Wahle
 

Semelhante a MDC 2022 Practical Blazor.pptx (20)

AEM Sightly Deep Dive
AEM Sightly Deep DiveAEM Sightly Deep Dive
AEM Sightly Deep Dive
 
Toms introtospring mvc
Toms introtospring mvcToms introtospring mvc
Toms introtospring mvc
 
Asp.NET MVC
Asp.NET MVCAsp.NET MVC
Asp.NET MVC
 
Building richwebapplicationsusingasp
Building richwebapplicationsusingaspBuilding richwebapplicationsusingasp
Building richwebapplicationsusingasp
 
JavaScript Framework Smackdown
JavaScript Framework SmackdownJavaScript Framework Smackdown
JavaScript Framework Smackdown
 
From Backbone to Ember and Back(bone) Again
From Backbone to Ember and Back(bone) AgainFrom Backbone to Ember and Back(bone) Again
From Backbone to Ember and Back(bone) Again
 
Novedades de MongoDB 3.6
Novedades de MongoDB 3.6Novedades de MongoDB 3.6
Novedades de MongoDB 3.6
 
Fly High With Angular - How to build an app using Angular
Fly High With Angular - How to build an app using AngularFly High With Angular - How to build an app using Angular
Fly High With Angular - How to build an app using Angular
 
Spring MVC Intro / Gore - Nov NHJUG
Spring MVC Intro / Gore - Nov NHJUGSpring MVC Intro / Gore - Nov NHJUG
Spring MVC Intro / Gore - Nov NHJUG
 
Design Patterns in ZK: Java MVVM as Model-View-Binder
Design Patterns in ZK: Java MVVM as Model-View-BinderDesign Patterns in ZK: Java MVVM as Model-View-Binder
Design Patterns in ZK: Java MVVM as Model-View-Binder
 
CTTDNUG ASP.NET MVC
CTTDNUG ASP.NET MVCCTTDNUG ASP.NET MVC
CTTDNUG ASP.NET MVC
 
AngularJS Beginner Day One
AngularJS Beginner Day OneAngularJS Beginner Day One
AngularJS Beginner Day One
 
Asp.net mvc training
Asp.net mvc trainingAsp.net mvc training
Asp.net mvc training
 
Ruby For Startups
Ruby For StartupsRuby For Startups
Ruby For Startups
 
KnockOutjs from Scratch
KnockOutjs from ScratchKnockOutjs from Scratch
KnockOutjs from Scratch
 
Jinal desai .net
Jinal desai .netJinal desai .net
Jinal desai .net
 
Beginning AngularJS
Beginning AngularJSBeginning AngularJS
Beginning AngularJS
 
PyData Berlin 2023 - Mythical ML Pipeline.pdf
PyData Berlin 2023 - Mythical ML Pipeline.pdfPyData Berlin 2023 - Mythical ML Pipeline.pdf
PyData Berlin 2023 - Mythical ML Pipeline.pdf
 
Spring framework in depth
Spring framework in depthSpring framework in depth
Spring framework in depth
 
angularJs Workshop
angularJs WorkshopangularJs Workshop
angularJs Workshop
 

Último

Intelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmIntelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmSujith Sukumaran
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based projectAnoyGreter
 
Best Web Development Agency- Idiosys USA.pdf
Best Web Development Agency- Idiosys USA.pdfBest Web Development Agency- Idiosys USA.pdf
Best Web Development Agency- Idiosys USA.pdfIdiosysTechnologies1
 
Buds n Tech IT Solutions: Top-Notch Web Services in Noida
Buds n Tech IT Solutions: Top-Notch Web Services in NoidaBuds n Tech IT Solutions: Top-Notch Web Services in Noida
Buds n Tech IT Solutions: Top-Notch Web Services in Noidabntitsolutionsrishis
 
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样umasea
 
Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)Ahmed Mater
 
英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作qr0udbr0
 
Implementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureImplementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureDinusha Kumarasiri
 
PREDICTING RIVER WATER QUALITY ppt presentation
PREDICTING  RIVER  WATER QUALITY  ppt presentationPREDICTING  RIVER  WATER QUALITY  ppt presentation
PREDICTING RIVER WATER QUALITY ppt presentationvaddepallysandeep122
 
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...Natan Silnitsky
 
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company OdishaBalasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odishasmiwainfosol
 
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEBATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEOrtus Solutions, Corp
 
Introduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfIntroduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfFerryKemperman
 
Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Hr365.us smith
 
SpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at RuntimeSpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at Runtimeandrehoraa
 
A healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdfA healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdfMarharyta Nedzelska
 
Folding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesFolding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesPhilip Schwarz
 
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024StefanoLambiase
 
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte GermanySuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte GermanyChristoph Pohl
 

Último (20)

Intelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmIntelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalm
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based project
 
Best Web Development Agency- Idiosys USA.pdf
Best Web Development Agency- Idiosys USA.pdfBest Web Development Agency- Idiosys USA.pdf
Best Web Development Agency- Idiosys USA.pdf
 
Buds n Tech IT Solutions: Top-Notch Web Services in Noida
Buds n Tech IT Solutions: Top-Notch Web Services in NoidaBuds n Tech IT Solutions: Top-Notch Web Services in Noida
Buds n Tech IT Solutions: Top-Notch Web Services in Noida
 
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
 
Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)
 
英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作
 
Implementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureImplementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with Azure
 
PREDICTING RIVER WATER QUALITY ppt presentation
PREDICTING  RIVER  WATER QUALITY  ppt presentationPREDICTING  RIVER  WATER QUALITY  ppt presentation
PREDICTING RIVER WATER QUALITY ppt presentation
 
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
 
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company OdishaBalasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
 
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEBATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
 
Introduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfIntroduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdf
 
Advantages of Odoo ERP 17 for Your Business
Advantages of Odoo ERP 17 for Your BusinessAdvantages of Odoo ERP 17 for Your Business
Advantages of Odoo ERP 17 for Your Business
 
Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)
 
SpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at RuntimeSpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at Runtime
 
A healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdfA healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdf
 
Folding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesFolding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a series
 
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
 
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte GermanySuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
 

MDC 2022 Practical Blazor.pptx

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7. PRACTICAL BLAZOR for Minnesota Developers Conference 2022 Patrick Szalapski Applications Architect, General Mills @Szalapski | szalapski.com
  • 8. AGENDA 1. Cross-cutting concerns, such as profiling, using abstract components 2. Speeding up rendering with virtualization 3. Avoiding rerendering with abstract components 4. Breaking a Blazor component into subcomponents
  • 9. DEMO • Ask me (now or afterward) about: • Mechanical keyboards • New File extension • Windows Terminal • Nullable and non-nullable references • Unhelpful VSPro removes “watch” • VS Intellisense slightly broken for Blazor • Refactor one step at a time, even if confident • Agile, Scrum, Kanban, team concerns This is Minnesota Developers Conference, not Minnesota Managers Conference: Let’s code, not read slides Tangents we might hit…  dotnet watch vs. VS run  speed up your development loop  Blazor favicon animated glyph  `null!` convention for required parameters
  • 10. MAKING A SUBCOMPONENT IN BLAZOR 1.Insert (non-working) markup calling the new subcomponent above old markup 2.Copy the entire component as new component 3.Delete unnecessary markup and code in subcomponent 4.Add parameters 5.Add “…Changed” EventCallback parameters 6.Test and fix as doubled-up behavior 7.In the parent, delete the doubled-up markup, code, directives
  • 11. MAKING A SUBCOMPONENT IN BLAZOR (ELABORATED) 1. Insert markup for the new subcomponent usage (above the markup that will be removed). 2. Copy the entire component to a new file. Rename it to match the above. 3. Edit the new subcomponent to delete all markup that should remain in the parent only. Delete all code that is thus unused. 4. Add parameters for missing references; supply them in the parent. 5. Add “…Changed” EventCallback parameters for anything editable. 6. Now you have a subcomponent that works and a parent that also works with its markup repeated (doubled up). Test and fix anything that is broken. 7. In the parent, delete the appropriate markup, code, and directives.
  • 12. BINDING REFERENCE <select value="Bob" /> a literal string “Bob“, obviously <select value="@myName" /> one-way binding: the rendered option always gets the updated value of myName <select @value="myName" /> AVOID - error: '@value' is not a valid attribute name. <select @value="@myName" /> AVOID - error: '@value' is not a valid attribute name. <select value="@myName“ @onchange="handleChange" /> one-way binding with event on change, a good approach when custom logic is needed (e.g saving to a web API then conditionally updating the value); note, handleChange is a reference to a function that takes one parameger, a ChangeEventArgs instance. <select @bind="@myName" /> Two-way binding using the special value attribute and onchange event; same as <select value="@myName" onchange="e => myName = e.Value" /> <select @bind-Item="myName" /> (or any attribute, not just "value") Two-way binding; same as <select Item="@myName" ItemChanged="e => myName = e.Value" /> <select @bind-Item="myName" @bind-Item:event="oninput" /> Two-way binding using custom event; same as <select Item="@myName" @oninput="e => myName = e.Value" /> <MyComponent MyParameter1="@("firstName")" /> (Custom component) Literal string <MyComponent MyParameter1="firstName" /> NOT a literal string; passes the value of firstName as a one-way binding <MyComponent MyParameter1="@firstName" /> AVOID - redundant <MyComponent @MyParameter1="…" /> AVOID - ERROR - bad syntax <MyComponent @bind-MyParameter1="…" /> Two-way binding; same as <MyComponent MyParameter1="myName" MyParameter1Changed="e => myName = e.Value" /> (both the MyParameter1 parameter and the MyParameter1Changed event must
  • 13. STRETCH GOAL: UNPREPARED BLAZOR CHAT • Get-only properties are better than mutating state • CallbackEvents can be bound to either synchronous or async methods • OnParametersSetAsync and OnAfterRender are the two methods you have to react to in a subcomponent

Notas do Editor

  1. 7
  2. When I first started working in component-based frameworks like Vue.js and Blazor, my instinct was often to make loops and then call a method from a binding inside of the loop.  After all, that's what we do in jQuery or even in everyday procedural programming, such as in a service or library function--when we have a loop, you use the properties of the objects we're looping over to make whatever call we want. But in web components, this logic can become much simpler by being eager to make a new subcomponent, moreso than your intuition might tell you. Usually breaking out the innards of a loop to its own component results in simpler code. Here's how you do it: In the original component, look at your loop; usually you will aim to refactor the entire contents of the loop (but not the loop flow control) into a new component. Choose a name for your component and insert markup for such an element (that doesn't yet exist), usually as the very first element inside the loop. It needs at least one parameter: the loop iteration reference. I like to name the parameter exactly the same as the loop iteration reference, as it makes the transition easier, which means it might be in camelCase and not PascalCase; this is temporary Copy the entire .razor component to a new .razor file that will become the child component. Rename the file to match the name you chose in step 1. If the component has a @page directive at the top of the new file, delete it. Rename that file to match the name you typed for the new element. Visual Studio unhelpfully edits your .csproj file to add a Watch-Remove element for the new component. I usually want to dotnet-watch all my components, so remove it from the .csproj file manually. Edit the new child component file markup to delete all content outside of and including the loop statement, leaving only the markup that was inside the loop. Add or modify the root-level element if desired. (I try always to have a root element with a class the same name as the component but in kebab-case.) Add a parameter member for the parameter you implied in step 1. It should be a public property with a getter and setter, and have a default value. Prefer it to be non-nullable if possible. Again, it might be in camelCase and not PascalCase; this is temporary. In the parent component, Visual Studio may give you the mistaken error "found markup with unexpected name", even though you are in the same folder and therefore the same namespace. Ignore it; it should compile anyway. This error might go away later when you reload Visual Studio. Look through the markup and see if there are any other missing references. There likely won't be, as you haven't yet deleted anything from the code section. If there are problems, fix them before continuing. At this point, your new markup in the parent component should work, and you should have a component that will compile and render the very same way, right above the old markup. Since you still have the same markup in the parent component, you can run it and see if you get the desired duplicated markup on the rendered page. If you do not, fix things before continuing. Put the new component and its parent on a diet Delete all the parts of the @code in the child component you no longer need; this is usually most of it. Also, delete any unneeded @inject directives and any unused @usings (for needs that were only in the parent and not here). Recompile and inspect it again, confirming that the new component is still identical to the old markup which still exists in the parent component. Go back to the parent component and delete the markup that is now being rendered in the child component. Also delete any code, @inject directives, or unused @usings that you can (for needs that were only in the child and not here). Recompile and inspect it again, confirming that the new component works well and that the old markup is gone. Fix its flaws Now that your component is fully baked, you can refactor it to make it simpler. Any bindings with arguments can likely now be argumentless, and the state for this iteration now simply becomes the state for the whole component instance. Finally, you can rename your new component's parameter to a better name with proper casing.   Done!