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

longestdrive's avatar

Updating a livewire select component - unexpected rendering issue

I'm trying to create a component that enables users to place players in groups/teams. In the component I create a default array that creates a structured array: $groups = [ 0=>[p1->id, p2->id, p3->id], 1=>[p4-id, p5->id, p6->id] ];

A form is displayed to show the current groups and the user can then change the group the user is in. A method in the component updates the array for that player and places them in the correct group that the user has selected.

However, on the form the select options are not updating correctly - it correctly shows the player moved into the new group but at the same time another player is shown as updated on the form incorrectly.

I can see that the '$groups' array correctly shows the values I expect - the data is correct

It seems that as the player visually is shifted to the new group that select box remains in place and not refreshed. strangely I can see if I inspect the HTML it all looks correct.

I need to be able to refresh the select boxes after a player has been moved to another group - how can I do this or overcome this issue?

Here's my component:

and here's my view:

select_box

I've attached a screen shot with the before selection and then the result after selecting group 2 for the what was second player in group 1. At the bottom of the form for testing I can see the contents of the $groups array which is correct

Unclear what the problem is :(

0 likes
6 replies
LaryAI's avatar
Level 58

The issue you're experiencing with the Livewire component not updating the select boxes correctly is likely due to how Livewire handles reactivity and DOM updates. When you change the group of a player, the component's state is updated, but the DOM might not be reflecting these changes correctly due to how the wire:change event is being handled.

To ensure that the select boxes are updated correctly, you can force a re-render of the component after updating the groups. One way to achieve this is by using the $refresh method provided by Livewire. This method will force the component to re-render, ensuring that the DOM is updated correctly.

Here's how you can modify your changePlayerGroup method to include a call to $refresh:

public function changePlayerGroup($playerId, $newGroupIndex)
{
    // Find the player and remove from the current group
    foreach ($this->groups as &$group) {
        foreach ($group as $key => $player) {
            if ($player->id == $playerId) {
                unset($group[$key]);
                break 2;
            }
        }
    }

    // Add the player to the new group
    $this->groups[$newGroupIndex][] = $this->players->find($playerId);

    // Force a re-render of the component
    $this->emitSelf('playersGroupChanged');
}

Additionally, ensure that your component is listening for the playersGroupChanged event and calling the $refresh method:

protected $listeners = [
    'playersGroupChanged' => '$refresh'
];

This will ensure that the component is re-rendered whenever the playersGroupChanged event is emitted, which should resolve the issue with the select boxes not updating correctly.

Here's the updated component code:

And here's the updated view:

This should ensure that the select boxes are updated correctly when a player is moved to a new group.

Chingy's avatar

What Livewire version are you using ?

longestdrive's avatar

@Chingy I’m using v3. I’ve tried adding the $refresh as suggested but it fails to render the selected drop down correctly .

Chingy's avatar

@longestdrive Seems like Dom diff issue. You need to add wire:keys on the elements that are inside a foreach loop. Also, i asked what version you using, because i saw @entangle, and that is deprecated. Changet it to $wire.entangle('myproperty').live

longestdrive's avatar

Hi. Thank you. I keep forgetting that step. Lesson learned.

Just added the wire:key and it works as expected.

Thank you

Please or to participate in this conversation.