Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

PttRulez's avatar
Level 21

wire keys and not displayed livewire component

Hey guys. Here is some par of livewire blade component. Inside foreach i insert my livewire component for search and just 3 inputs. I increase $foods variable just by clicking some '+' button. But when rows added, only inputs are displayed, while food-search component appears only in the first row

<div>
      @foreach($foods as $i => $food)
        <div class="grid grid-cols-[3fr_1fr_1fr_1fr] gap-2 mb-2" wire:key="{{ $i }}">
          <livewire:components.food-search />
          <input
            type='number'
            placeholder='0 г'
            class='input input-bordered w-full'
            wire:model="foods.{{ $i }}.weight"
          />

After playing around with chatgpt this is the solution which works

<div>
      @foreach($foods as $i => $food)
        <div class="grid grid-cols-[3fr_1fr_1fr_1fr] gap-2 mb-2" wire:key="{{ $i }}">
          <livewire:components.food-search  :key="'food-search' .  $i"/>
          <input
            type='number'
            placeholder='0 г'
            class='input input-bordered w-full'
            wire:model="foods.{{ $i }}.weight"
          />

I have 2 questions:

  1. Why do i even need key property in the nested component?
  2. And one more. If i put "wire:key" instead of just ":key" on food-search - the problem stays. only the first one is displayed. Since Alpine uses ":key" - i started suspecting that problem is connected with Alpine somehow.
0 likes
3 replies
PttRulez's avatar
Level 21

@Snapey don't we need to set key only for the parent element? In my case it is a div

LaryAI's avatar
Level 58

To address your questions, let's break down the issues and solutions related to Livewire components and the use of keys.

1. Why do you need the key property in the nested component?

In Livewire, the key property is crucial for ensuring that components are uniquely identified, especially when they are part of a loop. This is important for the following reasons:

  • State Management: Livewire uses the key to track the state of each component instance. Without a unique key, Livewire might not correctly differentiate between component instances, leading to unexpected behavior or rendering issues.

  • Performance Optimization: By providing a unique key, Livewire can optimize rendering by only updating the components that have changed, rather than re-rendering all components in the loop.

In your case, using :key="'food-search' . $i" ensures that each food-search component within the loop has a unique identifier, allowing Livewire to manage their states independently.

2. Why does using wire:key not work as expected?

The difference between wire:key and :key in this context is related to how Livewire and Alpine.js handle component keys:

  • wire:key: This is specific to Livewire and is used to uniquely identify elements within a Livewire component. It is typically used on HTML elements or Livewire components to ensure they are uniquely tracked by Livewire.

  • :key: This is a Vue.js/Alpine.js syntax for binding dynamic values. When used in a Livewire context, it can help ensure that nested Livewire components are uniquely identified, especially when they are dynamically generated.

In your scenario, using :key="'food-search' . $i" works because it provides a unique identifier for each food-search component instance. If wire:key is not working as expected, it might be due to how Livewire processes nested components differently from standard HTML elements.

Solution Recap

To ensure that each food-search component is rendered correctly, use the :key attribute to provide a unique identifier for each instance:

<div>
    @foreach($foods as $i => $food)
        <div class="grid grid-cols-[3fr_1fr_1fr_1fr] gap-2 mb-2" wire:key="{{ $i }}">
            <livewire:components.food-search :key="'food-search' . $i" />
            <input
                type='number'
                placeholder='0 г'
                class='input input-bordered w-full'
                wire:model="foods.{{ $i }}.weight"
            />
        </div>
    @endforeach
</div>

This approach ensures that each food-search component is uniquely identified and managed by Livewire, preventing issues with rendering and state management.

Please or to participate in this conversation.