Fixes hydration of Maps and Sets (#3960)
This commit is contained in:
parent
5fde2fd8bc
commit
ceda294e13
5 changed files with 50 additions and 5 deletions
5
.changeset/modern-bulldogs-burn.md
Normal file
5
.changeset/modern-bulldogs-burn.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
'astro': patch
|
||||
---
|
||||
|
||||
Fixes hydration of maps/sets
|
|
@ -4,12 +4,15 @@ import { useState } from 'react';
|
|||
interface Props {
|
||||
obj: BigNestedObject;
|
||||
num: bigint;
|
||||
arr: any[];
|
||||
map: Map<string, string>;
|
||||
set: Set<string>;
|
||||
}
|
||||
|
||||
const isNode = typeof process !== 'undefined' && Object.prototype.toString.call(process) === '[object process]';
|
||||
|
||||
/** a counter written in React */
|
||||
export default function Component({ obj, num, arr }: Props) {
|
||||
export default function Component({ obj, num, arr, map, set }: Props) {
|
||||
// We are testing hydration, so don't return anything in the server.
|
||||
if(isNode) {
|
||||
return <div></div>
|
||||
|
@ -24,6 +27,13 @@ export default function Component({ obj, num, arr }: Props) {
|
|||
<span id="bigint-value">{num.toString()}</span>
|
||||
<span id="arr-type">{Object.prototype.toString.call(arr)}</span>
|
||||
<span id="arr-value">{arr.join(',')}</span>
|
||||
<span id="map-type">{Object.prototype.toString.call(map)}</span>
|
||||
<ul id="map-items">{Array.from(map).map(([key, value]) => (
|
||||
<li>{key}: {value}</li>
|
||||
))}
|
||||
</ul>
|
||||
<span id="set-type">{Object.prototype.toString.call(set)}</span>
|
||||
<span id="set-value">{Array.from(set).join(',')}</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -12,6 +12,14 @@ const obj: BigNestedObject = {
|
|||
}
|
||||
}
|
||||
};
|
||||
|
||||
const map = new Map<string,string>();
|
||||
map.set('test1', 'test2');
|
||||
map.set('test3', 'test4');
|
||||
|
||||
const set = new Set<string>();
|
||||
set.add('test1');
|
||||
set.add('test2');
|
||||
---
|
||||
|
||||
<html lang="en">
|
||||
|
@ -22,7 +30,7 @@ const obj: BigNestedObject = {
|
|||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<Component client:load obj={obj} num={11n} arr={[0, "foo"]} />
|
||||
<Component client:load obj={obj} num={11n} arr={[0, "foo"]} map={map} set={set} />
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
import { expect } from '@playwright/test';
|
||||
import { testFactory } from './test-utils.js';
|
||||
|
||||
const test = testFactory({ root: './fixtures/pass-js/' });
|
||||
const test = testFactory({
|
||||
root: './fixtures/pass-js/'
|
||||
});
|
||||
|
||||
let devServer;
|
||||
|
||||
|
@ -53,4 +55,24 @@ test.describe('Passing JS into client components', () => {
|
|||
await expect(arrValue, 'is visible').toBeVisible();
|
||||
await expect(arrValue).toHaveText('0,foo');
|
||||
});
|
||||
|
||||
test('Maps and Sets', async ({ page }) => {
|
||||
await page.goto('/');
|
||||
|
||||
const mapType = page.locator('#map-type');
|
||||
await expect(mapType, 'is visible').toBeVisible();
|
||||
await expect(mapType).toHaveText('[object Map]');
|
||||
|
||||
const mapValues = page.locator('#map-items li');
|
||||
expect(await mapValues.count()).toEqual(2);
|
||||
|
||||
const texts = await mapValues.allTextContents();
|
||||
expect(texts).toEqual(['test1: test2', 'test3: test4']);
|
||||
|
||||
const setType = page.locator('#set-type');
|
||||
await expect(setType, 'is visible').toBeVisible();
|
||||
|
||||
const setValue = page.locator('#set-value');
|
||||
await expect(setValue).toHaveText('test1,test2');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -33,10 +33,10 @@ function convertToSerializedForm(value: any): [ValueOf<typeof PROP_TYPE>, any] {
|
|||
return [PROP_TYPE.RegExp, (value as RegExp).source];
|
||||
}
|
||||
case '[object Map]': {
|
||||
return [PROP_TYPE.Map, Array.from(value as Map<any, any>)];
|
||||
return [PROP_TYPE.Map, JSON.stringify(serializeArray(Array.from(value as Map<any, any>)))];
|
||||
}
|
||||
case '[object Set]': {
|
||||
return [PROP_TYPE.Set, Array.from(value as Set<any>)];
|
||||
return [PROP_TYPE.Set, JSON.stringify(serializeArray(Array.from(value as Set<any>)))];
|
||||
}
|
||||
case '[object BigInt]': {
|
||||
return [PROP_TYPE.BigInt, (value as bigint).toString()];
|
||||
|
|
Loading…
Reference in a new issue