I’ve made a very simple profile card with two views once is showing me the profile id,name and email and the second view just show the input fields for this three attributes.
This is working but it is “very” slow. When i’m hitting the button Edit on the show view, it takes more than 650ms(in best scenario, sometimes it takes more than 1.2sec) to load the edit view and vice versa.
How can I make this a little bit faster ?
Profile Component:
namespace App\Http\Livewire\User;
use App\User;
use Illuminate\Validation\Rule;
use Livewire\Component;
class Profile extends Component
{
public $user, $user_id, $name, $email;
public $updateMode = false;
public function mount(User $user)
{
$this->user = $user;
$this->user_id = $user->id;
$this->name = $user->name;
$this->email = $user->email;
}
public function render()
{
return view('livewire.user.profile.resource');
}
public function edit()
{
$this->updateMode = true;
}
public function cancel()
{
$this->updateMode = false;
}
public function submit()
{
$attributes = $this->validate([
'name' => 'required|min:6',
'email' => ['required', 'email', Rule::unique('users')->ignore($this->user->id)],
]);
$this->user->update($attributes);
$this->updateMode = false;
}
}
And this are the views: resource.blade.php:
<div >
@includeWhen(!$updateMode,'livewire.user.profile.show')
@includeWhen($updateMode,'livewire.user.profile.edit')
</div>
show.blade.php:
<div>
<div >
<div >
<span >Id:</span>
</div>
<div >
<span >{{ $user_id }}</span>
</div>
</div>
<div >
<div >
<span >Name:</span>
</div>
<div >
<span >{{ $name }}</span>
</div>
</div>
<div >
<div >
<span >Email:</span>
</div>
<div >
<span >{{ $email }}</span>
</div>
</div>
<!-- Editing Buttons -->
<div >
<button type="button" wire:click.prevent="edit" >Edit</button>
</div>
</div>
edit.blade.php:
<form wire:submit.prevent="submit">
<div >
<div >
<span >Id:</span>
</div>
<div >
<span >{{ $user_id }}</span>
</div>
</div>
<div >
<div >
<span >Name:</span>
</div>
<div >
<input type="text" wire:model="name">
</div>
</div>
<div >
<div >
<span >Email:</span>
</div>
<div >
<input type="text" wire:model="email">
</div>
</div>
<!-- Editing Buttons -->
<div >
<button type="submit" >Save</button>
<a href="#" wire:click.prevent="cancel">Cancel</a>
</div>
</form>
CodePudding user response:
I ran into the same issue, with the same implementation approach. I also noticed that it was a bit slow when Livewire would change the state to show/hide the form, so what I did was use Alpine.js for determining whether to show the form or not.
<div x-data="{ mode: 'view' }">
<div x-show="mode === 'edit'">
<div>
<!-- display form here -->
</div>
<button wire:click="update">
Save
</button>
<button @click.prevent="mode = 'view'">
Cancel
</button>
</div>
<div x-show="mode !== 'edit'">
<div>
<!-- profile displayed here -->
</div>
<button @click.prevent="mode = 'edit'">
Edit
</button>
</div>
</div>
Doing it this way resolved the issue with displaying the form, which feels really snappy and quick. I have run into a different issue since that I’m not sure how to address.
If I begin to type in the form to update the name, and quickly hit the save button before the requests to update the component properties complete, then what ever the properties were at the time that I hit the save button are what gets saved to the database, creating a race condition.
I’m still relatively new to the Livewire paradigm so I don’t have a good answer for this yet.