-
Notifications
You must be signed in to change notification settings - Fork 11.1k
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
[8.x] Fix $component not being reverted if component doesn't render #39595
[8.x] Fix $component not being reverted if component doesn't render #39595
Conversation
Feels pretty odd to just delete a lot of code from |
@taylorotwell All tests passing. The code hasn't been deleted, it's been moved. The code that has been moved is self-contained. It only has an effect if Here are some examples of the compiled output to demonstrate: BEFORE: code for a class component (indented for clarity). The <?php if (isset($component)) { $__componentOriginalf35a3d9ace38e6b373c8c989b27270a64979c7ad = $component; } ?>
<?php $component = $__env->getContainer()->make(App\Views\Components\Test::class, []); ?>
<?php $component->withName('test'); ?>
<?php if ($component->shouldRender()): ?>
<?php $__env->startComponent($component->resolveView(), $component->data()); ?>
<?php $component->withAttributes([]); ?>
<?php if (isset($__componentOriginalf35a3d9ace38e6b373c8c989b27270a64979c7ad)): ?>
<?php $component = $__componentOriginalf35a3d9ace38e6b373c8c989b27270a64979c7ad; ?>
<?php unset($__componentOriginalf35a3d9ace38e6b373c8c989b27270a64979c7ad); ?>
<?php endif; ?>
<?php echo $__env->renderComponent(); ?>
<?php endif; ?> AFTER: Now the <?php if (isset($component)) { $__componentOriginalf35a3d9ace38e6b373c8c989b27270a64979c7ad = $component; } ?>
<?php $component = $__env->getContainer()->make(App\Views\Components\Test::class, []); ?>
<?php $component->withName('test'); ?>
<?php if ($component->shouldRender()): ?>
<?php $__env->startComponent($component->resolveView(), $component->data()); ?>
<?php $component->withAttributes([]); ?>
<?php echo $__env->renderComponent(); ?>
<?php endif; ?>
<?php if (isset($__componentOriginalf35a3d9ace38e6b373c8c989b27270a64979c7ad)): ?>
<?php $component = $__componentOriginalf35a3d9ace38e6b373c8c989b27270a64979c7ad; ?>
<?php unset($__componentOriginalf35a3d9ace38e6b373c8c989b27270a64979c7ad); ?>
<?php endif; ?> BEFORE: code for a non-class component (indented for clarity). The <?php $__env->startComponent('components.test'); ?>
<?php if (isset($__componentOriginal30db0f1643a6503c95bd8eba93e50f3610c2071c)): ?>
<?php $component = $__componentOriginal30db0f1643a6503c95bd8eba93e50f3610c2071c; ?>
<?php unset($__componentOriginal30db0f1643a6503c95bd8eba93e50f3610c2071c); ?>
<?php endif; ?>
<?php echo $__env->renderComponent(); ?> AFTER: <?php $__env->startComponent('components.test'); ?>
<?php echo $__env->renderComponent(); ?> |
There is likely a breaking change in that I could do something like this manually in a Blade component: @component(SomeClass::class)
...
@endcomponent In this case, I know this isn't explicitly documented as a way to use components but some packages could be using them this way. |
Is there a way to solve this problem without those breaking changes? |
Ah I didn't realise that. I'll have a think 👍 |
@taylorotwell The case you've mentioned above doesn't actually compile properly on 8.x in the first place. This is the result of <?php if (isset($component)) { $__componentOriginal6efa67299e2643b286abf9beb6b681a6c243977f = $component; } ?>
<?php $component = $__env->getContainer()->make(SomeClass::class, []); ?>
<?php $component->withName(); ?>
<?php if ($component->shouldRender()): ?>
<?php $__env->startComponent($component->resolveView(), $component->data()); ?>
...
<?php if (isset($__componentOriginal6efa67299e2643b286abf9beb6b681a6c243977f)): ?>
<?php $component = $__componentOriginal6efa67299e2643b286abf9beb6b681a6c243977f; ?>
<?php unset($__componentOriginal6efa67299e2643b286abf9beb6b681a6c243977f); ?>
<?php endif; ?>
<?php echo $__env->renderComponent(); ?> Even if you change the code to: @component(SomeClass::class)
...
@endcomponentclass It fails with the error:
Can't be a breaking change if the functionality is already broken? 😅 |
OK - I'll give it a shot. |
If a component does not render due to its
shouldRender
method returning false, then the value of the$component
variable will never be reverted back to its original value.Example:
Expected output:
Actual output:
Fixed by moving the statements that revert
$component
outside of theshouldRender
conditional. Tests updated accordingly. As far as I can tell, these statements aren't needed inside ofcompileEndComponent
anyway, because the$component
variable is only overwritten when starting a class component.