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

harcodeddev's avatar

Can't re-render child of a component properly

I tried this, but initially, I was getting a snapshot error in the console. Now that error is gone, but I encountered a new issue. When I update the percentage of a progress circle, the view updates correctly, but all instances of that component end up displaying the same progress and color. If I refresh the page, each instance shows its correct percentage and color again. I've tried various approaches, including #[On] listeners and $dispatch, but nothing seems to work.

I'm currently learning Laravel and Livewire, but for some reason, Livewire 2 seemed more straightforward, or maybe I'm just too much of a noob

Here's my setup:



<?php

namespace App\Livewire;

use Livewire\Component;
use Livewire\Attributes\On;

class ProgressCircle extends Component
{
  public $progress;
  public $size;
  public $color;
  public $mode;

  public function mount($progress, $size, $color = 'blue', $mode = 'default')
  {
    $this->progress = $progress;
    $this->size = $size / 16 . 'rem';
    $this->color = $color;
    $this->mode = $mode;
  }
  #[On('cerrar-modal')]
  public function updateValues($data = null)
  {

    if ($data && isset($data['porcentaje'])) {
      $this->progress = intval($data['porcentaje']);
      $this->dispatch('renderizar');
    }
  }
  #[On('renderizar')]
  public function render()
  {

    $progressToRender = $this->progress;

    return view('livewire.progress-circle', [
      'progress' => $progressToRender,
      'size' => $this->size,
      'color' => $this->color,
      'mode' => $this->mode,
    ]);
  }
}

@push('scripts')
  <script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
@endpush

<div>
  <h1 class="text-2xl font-bold text-gray-600">Tus proyectos</h1>
  {{--   @if (session()->has('message'))
    <x-warnings> {{ session('message') }} </x-warnings>
  @endif --}}


  <div class="my-10">
    @forelse ($proyectos as $index => $proyecto)
      @switch($proyecto->status->id)
        @case($proyecto->status->id === 7)
          <div
            class="my-4 rounded border-t-4 border-red-600 bg-slate-100 p-4 dark:divide-gray-700 md:grid md:grid-cols-4">
          @break

          @case($proyecto->status->id === 4)
            <div
              class="my-4 rounded border-t-4 border-yellow-500 bg-slate-100 p-4 dark:divide-gray-700 md:grid md:grid-cols-4">
            @break

            @default
              <div
                class="my-4 rounded bg-slate-100 p-4 dark:divide-gray-700 md:grid md:grid-cols-4">
            @endswitch




            <div class="">
              <p class="text-sm capitalize text-gray-800 dark:text-gray-200">Nombre del proyecto: </p>
              <a href="{{ route('proyecto.show', $proyecto->id) }}">
                <p class="font-bold capitalize">{{ ucwords(strtolower($proyecto->nombre)) }}</p>
              </a>
              <p class="text-sm capitalize text-gray-800 dark:text-gray-200">Estatus Actual Del Proyecto: </p>

              <p class="font-bold capitalize">{{ ucwords(strtolower($proyecto->status->nombre)) }}</p>


              <p class="font-bold capitalize">{{ $proyecto->created_at->diffForHumans() }}</p>
            </div>
            <div class="">
              <p class="text-sm font-light">Descripción del proyecto</p>
              <p class="max-w-96 line-clamp-3 font-bold capitalize text-gray-800 dark:text-gray-200">
                {{ $proyecto->descripcion }}
              </p>
            </div>
            <div>
              <livewire:progress-circle :wire:key="$index.$proyecto->id" :progress="$proyecto->porcentaje" :size="192"
                :mode="'range'" />

            </div>
            <div>
              <x-primary-button wire:click="$dispatch('mostrarConfirmacion', {{ $proyecto->id }})"
                class="inline-flex w-full justify-center">Eliminar</x-primary-button>
              <x-primary-button x-data
                x-on:click="$dispatch('abrir-modal', { name: 'proyecto-{{ $proyecto->id }}' })"
                class="my-2 inline-flex w-full justify-center bg-indigo-600 text-center text-white">Editar</x-primary-button>
            </div>
          </div>
          <x-modal title="Editar proyecto" name="proyecto-{{ $proyecto->id }}">
            @slot('body')
              <livewire:edit-project key="{{ $proyecto->id }}" id="{{ $proyecto->id }}" />
            @endslot
          </x-modal>
          @empty
            <p class="p-4 text-center text-xl font-bold text-gray-600">Actualmente no tienes proyectos puedes empezar <a
                class="text-blue-700"
                href="{{ route('proyecto.create') }}">
                creando
                uno
              </a></p>
      @endforelse
      <div>{{ $proyectos->links() }}</div>
    </div>
    @script
      <script>
        window.addEventListener('mostrarConfirmacion', event => {
          Swal.fire({
            title: "¿Estás seguro?",
            text: "No podrás revertir esto!",
            icon: "warning",
            showCancelButton: true,
            confirmButtonColor: "#3085d6",
            cancelButtonColor: "#d33",
            confirmButtonText: "Sí, eliminar!",
            cancelButtonText: "Cancelar"
          }).then((result) => {
            if (result.isConfirmed) {
              Livewire.dispatch('destruirProyecto', [event.detail]);
              Swal.fire({
                title: "Eliminado!",
                text: "Tu archivo ha sido eliminado.",
                icon: "success"
              });
            }
          });
        });
      </script>
    @endscript
0 likes
0 replies

Please or to participate in this conversation.