Search code examples
razorblazorblazor-client-side

How do you render a list of components in a loop (Blazor)?


I must be missing something very obvious with blazor... I want to simply render a list containing a component, yet there's no (obvious?) way to reference the iterator (which is a component) for rendering?

TodoList.razor

<input @bind="_newTodo" />
<button @onclick="@AddTodoItem">+</button>

@foreach (TodoItem todoItem in _todoItems)
{
    // todoItem is a razor component, yet I can't simply render it here?
    // <todoItem />
}

@code {
    private IList<TodoItem> _todoItems = new List<TodoItem>();
    private string _newTodo;

    private void AddTodoItem()
    {
        if (!string.IsNullOrWhiteSpace(_newTodo))
        {
            _todoItems.Add(new TodoItem { Title = _newTodo });
            _newTodo = string.Empty;
        }
    }
}

TodoItem.razor

<span>@Title</span>

@code {
    public string Title { get; set; }
}

Solution

  • One solution to do that is have a class that holds the component properties and pass the properties to it

    <input @bind="_newTodo" />
    <button @onclick="@AddTodoItem">+</button>
    
    @foreach (TodoItem todoItem in _todoItemsDto)
    {
        // Pass the Dto properties to the component
        <TodoItem Title="@todoItem.Title" />
    }
    
    @code {
        private IList<TodoItemDto> _todoItemsDto = new List<TodoItemDto>();
        private string _newTodo;
    
        class TodoItemDto {
            public string Title { get; set; }
        }
    
        private void AddTodoItem()
        {
            if (!string.IsNullOrWhiteSpace(_newTodo))
            {
                _todoItems.Add(new TodoItemDto { Title = _newTodo });
                _newTodo = string.Empty;
            }
        }
    }