데이터 바인딩 기초
단방향·양방향 데이터 바인딩으로 UI와 데이터를 연결하는 방법을 배웁니다.
📌 학습 목표
- 데이터 바인딩의 개념과 Blazor에서의 역할을 설명할 수 있다.
- 단방향 바인딩(@변수, @(표현식))으로 C# 데이터를 HTML에 표시할 수 있다.
- 양방향 바인딩(@bind)으로 사용자 입력을 C# 변수에 자동 동기화할 수 있다.
- @bind-Value:event를 사용해 바인딩 업데이트 시점(oninput / onchange)을 제어할 수 있다.
- 체크박스·select·textarea 등 다양한 입력 요소에 @bind를 적용할 수 있다.
| 항목 | 단방향 바인딩 | 양방향 바인딩 |
|---|---|---|
| 문법 | @변수명 / @(표현식) | @bind=’변수명’ |
| 데이터 흐름 | C# → UI (출력 전용) | C# ↔ UI (출력 + 입력) |
| 주요 사용처 | 텍스트 출력, 계산 결과 표시 | 폼 입력, 체크박스, 선택 목록 |
| 업데이트 기본 이벤트 | 렌더링 시 자동 | onchange (포커스 이탈 시) |
| 실시간 반응 설정 | 해당 없음 | @bind-Value:event=’oninput’ |
📝 개념 설명
1. 데이터 바인딩이란?
데이터 바인딩(Data Binding)이란 C# 코드의 데이터(변수, 속성)와 HTML UI 요소를 자동으로 연결하는 메커니즘입니다. 바인딩이 설정되면 C# 변수가 변경될 때 UI가 자동 업데이트되고, 사용자가 UI를 변경할 때 C# 변수도 자동으로 갱신됩니다.
Blazor는 컴포넌트 기반 프레임워크로, 각 컴포넌트는 자신만의 상태(state)를 보유합니다. 데이터 바인딩은 이 상태와 UI를 동기화하는 핵심 기능이며, jQuery나 별도 JavaScript 없이 순수 C# 코드만으로 동적 UI를 구현할 수 있게 해줍니다.
• 이벤트 핸들러(@onclick, @oninput 등) 실행이 끝나면 Blazor가 자동으로 StateHasChanged()를 호출합니다.
• 코드에서 직접 StateHasChanged()를 호출해도 됩니다.
• 부모 컴포넌트가 자식 컴포넌트의 파라미터를 업데이트할 때도 재렌더링이 발생합니다.
2. 단방향 데이터 바인딩 — @ 표현식
단방향 바인딩은 C# 변수나 표현식의 값을 HTML에 출력(읽기)하는 방식입니다. @ 기호로 C# 변수나 표현식을 HTML 마크업에 직접 삽입합니다.
<!-- Counter.razor -->
@page "/counter"
<h3>현재 카운트: @count</h3>
<p>두 배 값: @(count * 2)</p>
<p>상태: @(count >= 10 ? "목표 달성!" : "계속 클릭하세요")</p>
<button @onclick='Increment'>증가</button>
@code {
private int count = 0;
private void Increment()
{
count++;
}
}핵심 포인트:
@count— 변수 값을 그대로 출력 (단순 단방향 바인딩)@(count * 2)— C# 표현식을 괄호로 감싸 출력 (복합 표현식)@(count >= 10 ? "..." : "...")— 삼항 연산자 같은 복잡한 표현식도 사용 가능- 버튼 클릭 → Increment() 실행 → count 변경 → Blazor가 자동으로 UI 재렌더링
3. 양방향 데이터 바인딩 — @bind
양방향 바인딩은 UI의 입력값이 변경될 때 C# 변수도 자동으로 업데이트되는 방식입니다. @bind 디렉티브를 사용하며, 단방향 출력과 이벤트 처리를 한 번에 연결합니다.
<!-- TwoWayBinding.razor -->
@page "/twoway"
<h3>이름 입력</h3>
<input @bind='userName' placeholder='이름을 입력하세요' />
<p>안녕하세요, <strong>@userName</strong> 님!</p>
<h3>나이 입력</h3>
<input type='number' @bind='age' />
<p>10년 후 나이: @(age + 10)세</p>
@code {
private string userName = string.Empty;
private int age = 0;
}@bind='userName'은 내부적으로 두 가지 동작을 결합합니다:
- 값 출력:
value='@userName'형태로 C# 변수 값을 input에 표시 - 값 입력: onchange 이벤트(포커스 이탈) 발생 시 input 값을 C# 변수에 저장
즉, @bind는 value 속성 바인딩 + onchange 이벤트 핸들러를 자동으로 설정해주는 편의 디렉티브입니다.
4. @bind-Value와 바인딩 이벤트 제어
@bind의 기본 이벤트는 onchange입니다. 텍스트를 입력해도 포커스를 벗어나기 전까지는 C# 변수가 업데이트되지 않습니다. 키 입력마다 즉시 반응하게 하려면 @bind-Value:event='oninput'을 사용합니다.
<!-- BindEvent.razor -->
@page "/bind-event"
<h3>실시간 반응 — oninput</h3>
<input @bind-Value='searchText'
@bind-Value:event='oninput'
placeholder='검색어를 입력하세요' />
<p>검색어: <mark>@searchText</mark></p>
<h3>포커스 이탈 시 반응 — onchange (기본값)</h3>
<input @bind='delayedText' placeholder='클릭 후 다른 곳 클릭해보세요' />
<p>입력값: @delayedText</p>
@code {
private string searchText = string.Empty;
private string delayedText = string.Empty;
}• oninput: 키를 누를 때마다 즉시 업데이트 → 실시간 검색, 글자 수 카운트, 미리보기에 적합
• onchange: 포커스가 벗어날 때 업데이트 → 폼 제출, 유효성 검사, 서버 API 호출에 적합 (기본값)
5. 체크박스 · select 바인딩
@bind는 텍스트 input 외에도 다양한 HTML 폼 요소에 적용할 수 있습니다. Blazor는 요소 타입에 따라 자동으로 적절한 속성(value 또는 checked)에 바인딩합니다.
<!-- FormBinding.razor -->
@page "/form-binding"
<!-- 체크박스: bool 타입 변수에 바인딩 -->
<label>
<input type='checkbox' @bind='isChecked' />
알림 수신 동의
</label>
<p>동의 여부: @(isChecked ? "✅ 동의함" : "❌ 미동의")</p>
<!-- select: string 타입 변수에 바인딩 -->
<select @bind='selectedLevel'>
<option value=''>난이도 선택</option>
<option value='beginner'>초급</option>
<option value='intermediate'>중급</option>
<option value='advanced'>고급</option>
</select>
<p>선택한 난이도: <strong>@selectedLevel</strong></p>
@code {
private bool isChecked = false;
private string selectedLevel = string.Empty;
}💡 예제 & 실습
실습: 실시간 글자 수 카운터 만들기
사용자가 텍스트를 입력할 때마다 남은 글자 수를 실시간으로 표시하는 컴포넌트를 구현합니다. 단방향·양방향 바인딩과 C# 로직을 통합하는 종합 예제입니다.
<!-- CharacterCounter.razor -->
@page "/char-counter"
<h3>자기소개 작성</h3>
<textarea
@bind-Value='bio'
@bind-Value:event='oninput'
maxlength='200'
rows='5'
placeholder='자기소개를 입력하세요 (최대 200자)'
style='width: 100%; resize: vertical;'>
</textarea>
<p style='font-weight: bold; color: @GetCountColor();'>
@bio.Length / 200자
</p>
@if (bio.Length >= 200)
{
<div class='qb-intro'>⚠️ 최대 글자 수에 도달했습니다.</div>
}
<h4>미리보기:</h4>
<div style='border: 1px solid #ccc; padding: 1rem; border-radius: 4px; min-height: 60px;'>
@if (string.IsNullOrWhiteSpace(bio))
{
<em style='color: #aaa;'>내용을 입력하면 여기에 표시됩니다.</em>
}
else
{
@bio
}
</div>
@code {
private string bio = string.Empty;
private string GetCountColor()
{
if (bio.Length >= 180) return "red";
if (bio.Length >= 120) return "orange";
return "#555";
}
}- @bind-Value:event=’oninput’ — 키 입력마다 bio 변수를 즉시 업데이트 (실시간 반응)
- @bio.Length — 단방향 바인딩으로 현재 글자 수 표시 (bio 변경 → Blazor 자동 재렌더링)
- GetCountColor() — C# 메서드를 style 속성 안에서 호출해 동적 색상 적용
- @if / else 블록 — Blazor 템플릿 안에서 C# 제어문을 직접 사용해 조건부 UI 렌더링
- string.IsNullOrWhiteSpace(bio) — 빈 입력 감지로 안내 텍스트를 대체 표시
bio = “”
(화면 표시)
(즉시 발생)
bio = “입력내용”
(글자 수 갱신)
⚠️ 자주 틀리는 것 / 주의사항
@bind를 사용하면서 value 속성을 따로 지정하면 컴파일 오류가 발생합니다.
❌
<input @bind='name' value='@name' /> — 컴파일 오류 (속성 충돌)✅
<input @bind='name' /> — @bind 단독 사용@bind는 내부적으로 value 속성 설정을 포함하므로 중복 지정이 불가합니다.
@bind의 기본 이벤트는 onchange입니다. 텍스트를 입력해도 포커스를 벗어나기 전까지 C# 변수가 업데이트되지 않습니다.
실시간 반응이 필요하다면 반드시
@bind-Value:event='oninput'을 명시하세요.string 타입 변수를 초기화하지 않고 .Length 같은 속성을 호출하면 런타임 오류가 발생합니다.
❌
private string name; — 암묵적 null, .Length 호출 시 오류✅
private string name = string.Empty; — 빈 문자열로 안전하게 초기화일반 HTML처럼 textarea 태그 사이에 초기값을 작성하면 Blazor에서 동작하지 않습니다.
❌
<textarea>기본값</textarea> — Blazor 렌더링 후 반영되지 않음✅
<textarea @bind='content'></textarea> + C#에서 private string content = "기본값";으로 초기화자식 컴포넌트의 [Parameter] 속성에 양방향 바인딩을 걸 때는
@bind-파라미터명 문법을 사용해야 합니다.자식 컴포넌트에
[Parameter] public string Value { get; set; }이 있다면부모에서
<ChildComponent @bind-Value='parentVar' /> 형태로 사용합니다. 이를 위해 자식 컴포넌트에는 ValueChanged EventCallback도 함께 선언해야 합니다.🎯 마무리
데이터 바인딩은 Blazor 애플리케이션에서 UI와 데이터를 동기화하는 핵심 메커니즘입니다. 단방향 바인딩(@변수)으로 C# 데이터를 화면에 출력하고, 양방향 바인딩(@bind)으로 사용자 입력을 즉시 반영하면, 순수 C# 코드만으로 반응형 UI를 구현할 수 있습니다.
- 실시간 검색 필터·글자 수 카운터·미리보기 →
@bind-Value:event='oninput'사용 - 회원가입·설정 폼·서버 API 호출 → 기본
@bind(onchange) 사용 - 계산 결과·상태 메시지·읽기 전용 데이터 → 단방향
@변수로 충분 - C# 표현식은
@(표현식)으로 HTML 어디서든 자유롭게 삽입 가능
- 단방향 바인딩:
@변수명/@(표현식)→ C# 데이터를 HTML에 출력 (읽기 전용) - 양방향 바인딩:
@bind='변수명'→ 입력 ↔ C# 변수 자동 동기화 - @bind의 기본 이벤트는 onchange (포커스 이탈 시 업데이트)
- 즉시 반응이 필요하면 @bind-Value:event=’oninput’ 명시 필요
- 체크박스(bool), select(string), textarea 등 다양한 폼 요소에 @bind 적용 가능
- string 변수는 반드시 string.Empty로 초기화해 NullReferenceException 방지
- @bind와 value 속성은 동시에 사용 불가 — @bind 단독 사용 원칙