phplaravellaravel-livewire

Livewire: component not reloading when switching routes with same view


Problem explanation

I'm using Livewire with an abstract base component (AbstractRecipeList) that handles common logic like render() and returns the same view (livewire.recipe-list) for all child components.

Child components:

Each of them returns a different base query in getBaseQuery(), but they all use the same Blade view.

Each route loads the correct component, the recipes displayed are different for each route, livewire components work properly when loaded directly.

Issue

When navigating between pages like:

/users/profiles/1/liked

/users/profiles/1/saved

If I'll try to navigate from /recipes (route for FilteredRecipes.php) to /users/profiles/1/liked I also don't have refresh

the URL updates, the data changes (recipes are different), but the component doesn't seem to re-render. No loading, no Livewire reset — just a silent switch in content.

What have I tried

Adding wire:key="...", but it didn't help me

Code:

AbsctractRecipeList.php:

abstract class AbstractRecipeList extends Component
{
    use WithPagination;

    public string $sort = 'popularity';

    public function render()
    {
        $recipes = $this->getRecipes();
        $recipes = $recipes->paginate(2)->withQueryString();

        return view('livewire.recipe-list', [
            'recipes' => $recipes
        ]);
    }

    abstract protected function getBaseQuery(): Builder;

    protected function getRecipes(){
        $query = $this->getBaseQuery()
            ->with(...)
            ->withCount(...);

        return $this->applySorting($query);
    }

    public function applySorting($query)
    {
        return match ($this->sort){
            'popularity' => $query->orderByDesc('savedCount')
             // other cases
        };
    }
}

FilteredRecipes.php:

class FilteredRecipes extends AbstractRecipeList
{
    public function mount(RecipeFilterRequest $request): void
    {
       // mount 
    }

    public function getBaseQuery(): Builder
    {
        // Filter logic using URL parameters
        $query = Recipe::when(...) // filter logic here

        return $query;
    }
}

SavedRecipes.php:

class SavedRecipes extends AbstractRecipeList
{
    public function getBaseQuery(): Builder
    {
        return auth()->user()->savedRecipes()->getQuery();
    }
}

LikedRecipes.php:

class LikedRecipes extends AbstractRecipeList
{
    public function getBaseQuery(): Builder
    {
        return auth()->user()->likedRecipes()->getQuery();
    }
}

And when I need to call those child components I am using:

<livewire:filtered-recipes />

<livewire:liked-recipes />

<livewire:saved-recipes />

Would be grateful for your help


Solution

  • Livewire treats components with the same view/DOM as identical, so it doesn't re-initialize on route change.

    Fix: Add a dynamic wire:key based on the route to force reload:

    blade
    

    <livewire:liked-recipes :wire:key="'liked-recipes-' . request()->path()" />

    Or emit a custom event on route change and handle it in mount or updated to manually refresh the data.