New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fixed: Livewire subcomponent clears render context after it is finished #2786
Fixed: Livewire subcomponent clears render context after it is finished #2786
Conversation
…to the parent component when using blade components
Thanks @joshhanley , all of the above makes sense. I think you're right on with needing to convert to a stack. Of you're up for it, I'd put course love a PR. Thanks man! |
@calebporzio have pushed up the fix 🙂 |
🎉 Confirmed! @joshhanley @calebporzio Now I'll go out on my balcony and do some crazy jumping while shouting out to the world, that the lid finally popped off the Livewire jar 💖 (Then I'll remove some nasty hacks from the tall-forms package that worked around this issue.) Sending LOVE! |
{ | ||
$this->livewireComponent = $component; | ||
return ! empty($this->livewireComponents); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe it's just me but I prefer:
return filled($this->livewireComponents);
My brain get's confused by negations.
Thanks Josh! You're the man! |
No worries 🙂 I'm glad it helps! |
Thanks @joshhanley!, that solved my problem |
Issue
This PR adds a failing test for the issue raised in #2313 and #2380.
If you make use of
$this
within a blade component to access the main Livewire component, it works fine.But when you add a Livewire subcomponent to the page and then try to add a blade component after the subcomponent that tries to access
$this
to access the main Livewire component, you get the following errorThis test demonstrates the issue.
Cause
I have dug into what causes the issue, and the problem exists in Livewire's blade compiler engine.
What happens is in ComponentConcerns/RendersLivewireComponents.php the Livewire component is bound to the
$this
context.At the top of the same function it does a check for
isRenderingLivewireComponent
, which if true, enables the render context to be set to the Livewire component, which is also applied to blade components.livewire/src/ComponentConcerns/RendersLivewireComponents.php
Lines 36 to 51 in 33101c8
The issue is though, that after a sub component is finished rendering it calls the
endLivewireRendering
method which setsisRenderingLivewireComponent
to false.livewire/src/ComponentConcerns/RendersLivewireComponents.php
Lines 24 to 27 in 33101c8
This then stops the blade components from having this context set, throwing the above error as there is no
$this
set at all.Temporary Fix
As a temporary solution (note this is a hack as a word around for the moment), I have added a blade directive to my
AppServiceProvider
Then in my Livewire component blade view, I add the call to that blade directive after any sub component
Possible Solution
To fix this, I think we need to change the boolean to an array and "stack" each components name into the array and use the last one as the context. Then when a component has finished it can pop itself off the end of the stack. The check can then see if there is anything left in the stack as to whether to bind a Livewire context or not.
The regular blade compiler makes use of a similar concept with
lastCompiled
where each view is pushed on to the "stack" (array) and removed once it has finished compiling.Happy to give it a crack if you think it is suitable.
Hope this helps!