Skip to content
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

text is undefined error with hydrated slotted component with default slot contents using bound computed properties #1144

Closed
jacobmischka opened this issue Feb 2, 2018 · 3 comments

Comments

@jacobmischka
Copy link
Contributor

The setup is as convoluted as the title suggests, ha. I'm trying to do something pretty stupid, so I'm not exactly surprised that things break, but I found it interesting it seems to happen only when all of these conditions are met.

Essentially, I'm trying to duplicate Vue's scoped slots using a bound property. The parent renders a slotted component, passing in data and receiving some transformed data back using a bound property. The slotted component has some default content which is being overridden from the parent, but both contents are rendered using the same computed value.

This all works in a normal component, but it breaks when the component is hydrated after being server rendered. As such, if using Sapper you navigate to the page, everything works, but if you reload the page it breaks. Additionally, if the slotted child doesn't have any default content, everything works fine as well.

Repro repo

peek 2018-02-01 22-48

(That HMR error is unrelated, the same thing happens when running in production mode).

Parent:

<Layout page='about'>
	<Slotted num="{{num}}" bind:computedNum="computedNum">
		<p style="color: red;">
			{{computedNum}}
		</p>
	</Slotted>
</Layout>

<script>
	import Layout from './_components/Layout.html';
	import Slotted from './_components/Slotted.html';

	export default {
		data() {
			return {
				num: 1
			};
		},
		components: {
			Layout,
			Slotted
		}
	};
</script>

Slotted child:

<select bind:value="someState">
	<option>a</option>
	<option>b</option>
	<option>c</option>
</select>

<slot>
	<span>{{computedNum}}</span>
</slot>

{{someState}}

<script>
	export default {
		data() {
			return {
				someState: 'a'
			};
		},
		computed: {
			computedNum(num, someState) {
				if (!num)
					return;

				return `${someState}:${num}`;
			}
		}
	};
</script>

Thanks!

@Rich-Harris
Copy link
Member

Finally taking a poke at this — it's a hell of a bug. Think I've whittled it down to this — if the default slotted content has anything dynamic, it causes problems.

Your repro was using Sapper 0.5.1 which actually got hydrating backwards (the only time it didn't hydrate was on the first load), so this isn't a hydration bug per se.

Closing in on a fix...

Rich-Harris added a commit that referenced this issue Feb 24, 2018
Rich-Harris added a commit that referenced this issue Feb 24, 2018
wrap <slot> updates in conditional
@Rich-Harris
Copy link
Member

Fixed in 1.56 — thanks

@jacobmischka
Copy link
Contributor Author

Woo thanks, nice work!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants