Blazor from Scratch: अध्याय 3 — स्केलेबल कॉम्पोनेंट्स
Blazor from Scratch के अध्याय 3 में आपका स्वागत है। अगर आपने अध्याय 2 मिस किया है, तो पहले उसे पढ़ लें ताकि आपका बेस प्रोजेक्ट तैयार हो।
अध्याय 2 में हमने ऐप रन किया। इस अध्याय में हम इसे maintainable बनाएंगे।
Blazor प्रोजेक्ट जल्दी messy हो जाते हैं जब हर पेज एक बड़ा .razor फाइल बन जाता है। कॉम्पोनेंट्स इस समस्या का समाधान हैं: consistency, reuse और UI के बीच clear boundaries।
Blazor component वास्तव में क्या है?
Component एक .razor फाइल है जो:
- Markup render करती है
- Local state रखती है
- Parameters से input लेती है
- Parent component को events भेजती है
- Child content render करती है
Runtime में Blazor हर component को एक छोटी state machine की तरह संभालता है। State बदलते ही re-render होता है और DOM diff apply होता है।
इसलिए आपका लक्ष्य होना चाहिए: साफ inputs और predictable behavior।
Step 1: focused component से शुरू करें
Components/Common/SectionHeader.razor बनाएं:
<header class="section-header">
<h2>@Title</h2>
@if (!string.IsNullOrWhiteSpace(Subtitle))
{
<p>@Subtitle</p>
}
</header>
@code {
[Parameter] public string Title { get; set; } = string.Empty;
[Parameter] public string? Subtitle { get; set; }
}
इसे Components/Pages/Home.razor में यूज़ करें:
@page "/"
<PageTitle>Blazor from Scratch</PageTitle>
<SectionHeader
Title="Blazor from Scratch"
Subtitle="Chapter 3 components पर है।" />
यह छोटा उदाहरण है, लेकिन core idea यही है: component उसके parameters से समझ में आना चाहिए।
Step 2: behavior को parameters से explicit करें
अब reusable button बनाते हैं।
Components/Common/AppButton.razor:
<button class="app-button @VariantCssClass" @onclick="OnClick">
@Text
</button>
@code {
[Parameter] public string Text { get; set; } = "Button";
[Parameter] public string Variant { get; set; } = "primary";
[Parameter] public EventCallback OnClick { get; set; }
private string VariantCssClass => Variant.ToLowerInvariant() switch
{
"secondary" => "app-button--secondary",
"danger" => "app-button--danger",
_ => "app-button--primary"
};
}
Usage:
@code {
private int _savedCount;
private void Save()
{
_savedCount++;
}
}
<AppButton Text="Save" Variant="primary" OnClick="Save" />
<p>Saved @_savedCount times.</p>
यहां महत्वपूर्ण चीज़ contract design है:
- छोटे और clear parameters
- Explicit naming, hidden magic नहीं
- Safe defaults
Step 3: layout composition के लिए RenderFragment
RenderFragment से parent, child component को UI blocks भेज सकता है।
Components/Common/Card.razor बनाएं:
<article class="card">
<header class="card__header">@Title</header>
<section class="card__body">
@ChildContent
</section>
</article>
@code {
[Parameter] public string Title { get; set; } = string.Empty;
[Parameter] public RenderFragment? ChildContent { get; set; }
}
Usage:
<Card Title="Roadmap">
<ul>
<li>Components</li>
<li>Data binding</li>
<li>Routing</li>
</ul>
</Card>
यह pattern consistent structure देता है और wrapper markup दोहराने से बचाता है।
Step 4: giant pages की बजाय composition चुनें
अगर page बड़ा हो रहा है, responsibility के हिसाब से split करें:
ProfileSummaryfor identity blockProfileStatsfor metricsProfileActivityListfor recent activity
इससे page orchestration layer बनता है, implementation dump नहीं।
Step 5: markup और logic का संतुलन रखें
Simple components के लिए inline @code ठीक है।
Bigger components के लिए code-behind उपयोग करें:
UserCard.razorUserCard.razor.cs
इससे markup और C# logic दोनों readable रहते हैं।
Step 6: practical folder structure
एक structure जो अच्छे से scale होता है:
Components/Pages/-> routable pagesComponents/Layout/-> app shell और navigationComponents/Common/-> shared generic blocksComponents/Features/<FeatureName>/-> feature-specific components
शुरुआती Blazor projects में common mistakes
- Dedicated view model की जगह बहुत ज्यादा parameters देना
- Business rules को page components में डाल देना
- Hundreds of lines वाला “God component” बना देना
- Repeated markup patterns को extract न करना
अगले अध्याय में
अध्याय 4 में हम data binding और events पर जाएंगे: @bind, event handling, two-way binding tradeoffs और predictable state patterns।