main
js 226 lines 4.65 KB
Raw
1 /**
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 *
7 * @flow
8 */
9
10 import * as React from 'react';
11 import {Fragment, useDebugValue, useState} from 'react';
12
13 const div = document.createElement('div');
14 const exampleFunction = () => {};
15 const typedArray = new Uint8Array(3);
16 typedArray[0] = 1;
17 typedArray[1] = 2;
18 typedArray[2] = 3;
19
20 const arrayOfArrays = [
21 [
22 ['a', 'b', 'c'],
23 ['d', 'e', 'f'],
24 ['h', 'i', 'j'],
25 ],
26 [
27 ['k', 'l', 'm'],
28 ['n', 'o', 'p'],
29 ['q', 'r', 's'],
30 ],
31 [['t', 'u', 'v'], ['w', 'x', 'y'], ['z']],
32 [],
33 ];
34
35 const objectOfObjects = {
36 foo: {
37 a: 1,
38 b: 2,
39 c: 3,
40 },
41 bar: {
42 e: 4,
43 f: 5,
44 g: 6,
45 },
46 baz: {
47 h: 7,
48 i: 8,
49 j: 9,
50 },
51 qux: {},
52 quux: {
53 k: undefined,
54 l: null,
55 },
56 };
57
58 function useOuterFoo() {
59 useDebugValue({
60 debugA: {
61 debugB: {
62 debugC: 'abc',
63 },
64 },
65 });
66 useState({
67 valueA: {
68 valueB: {
69 valueC: 'abc',
70 },
71 },
72 });
73 return useInnerFoo();
74 }
75
76 function useInnerFoo() {
77 const [value] = useState([[['a', 'b', 'c']]]);
78 return value;
79 }
80
81 function useOuterBar() {
82 useDebugValue({
83 debugA: {
84 debugB: {
85 debugC: 'abc',
86 },
87 },
88 });
89 return useInnerBar();
90 }
91
92 function useInnerBar() {
93 useDebugValue({
94 debugA: {
95 debugB: {
96 debugC: 'abc',
97 },
98 },
99 });
100 const [count] = useState(123);
101 return count;
102 }
103
104 function useOuterBaz() {
105 return useInnerBaz();
106 }
107
108 function useInnerBaz() {
109 const [count] = useState(123);
110 return count;
111 }
112
113 const unusedPromise = Promise.resolve();
114 const usedFulfilledPromise = Promise.resolve();
115 const usedFulfilledRichPromise = Promise.resolve({
116 some: {
117 deeply: {
118 nested: {
119 object: {
120 string: 'test',
121 fn: () => {},
122 },
123 },
124 },
125 },
126 });
127 const usedPendingPromise = new Promise(resolve => {});
128 const usedRejectedPromise = Promise.reject(
129 // eslint-disable-next-line react-internal/prod-error-codes
130 new Error('test-error-do-not-surface'),
131 );
132
133 class DigestError extends Error {
134 digest: string;
135 constructor(message: string, options: any, digest: string) {
136 super(message, options);
137 this.digest = digest;
138 }
139 }
140
141 export default function Hydration(): React.Node {
142 return (
143 <Fragment>
144 <h1>Hydration</h1>
145 <DehydratableProps
146 html_element={div}
147 fn={exampleFunction}
148 symbol={Symbol('symbol')}
149 react_element={<span />}
150 array_buffer={typedArray.buffer}
151 typed_array={typedArray}
152 date={new Date()}
153 array={arrayOfArrays}
154 object={objectOfObjects}
155 unusedPromise={unusedPromise}
156 usedFulfilledPromise={usedFulfilledPromise}
157 usedFulfilledRichPromise={usedFulfilledRichPromise}
158 usedPendingPromise={usedPendingPromise}
159 usedRejectedPromise={usedRejectedPromise}
160 // eslint-disable-next-line react-internal/prod-error-codes
161 error={new Error('test')}
162 // eslint-disable-next-line react-internal/prod-error-codes
163 errorWithCause={new Error('one', {cause: new TypeError('two')})}
164 errorWithDigest={new DigestError('test', {}, 'some-digest')}
165 // $FlowFixMe[cannot-resolve-name] Flow doesn't know about DOMException
166 domexception={new DOMException('test')}
167 />
168 <DeepHooks />
169 </Fragment>
170 );
171 }
172
173 function Use({value}: {value: Promise<mixed>}): React.Node {
174 React.use(value);
175 return null;
176 }
177
178 class IgnoreErrors extends React.Component {
179 state: {hasError: boolean} = {hasError: false};
180 static getDerivedStateFromError(): {hasError: boolean} {
181 return {hasError: true};
182 }
183
184 render(): React.Node {
185 if (this.state.hasError) {
186 return null;
187 }
188 return this.props.children;
189 }
190 }
191
192 function DehydratableProps({array, object}: any) {
193 return (
194 <ul>
195 <li>array: {JSON.stringify(array, null, 2)}</li>
196 <li>object: {JSON.stringify(object, null, 2)}</li>
197 <React.Suspense>
198 <Use value={usedPendingPromise} />
199 </React.Suspense>
200 <React.Suspense>
201 <Use value={usedFulfilledPromise} />
202 </React.Suspense>
203 <React.Suspense>
204 <Use value={usedFulfilledRichPromise} />
205 </React.Suspense>
206 <IgnoreErrors>
207 <React.Suspense>
208 <Use value={usedRejectedPromise} />
209 </React.Suspense>
210 </IgnoreErrors>
211 </ul>
212 );
213 }
214
215 function DeepHooks(props: any) {
216 const foo = useOuterFoo();
217 const bar = useOuterBar();
218 const baz = useOuterBaz();
219 return (
220 <ul>
221 <li>foo: {foo}</li>
222 <li>bar: {bar}</li>
223 <li>baz: {baz}</li>
224 </ul>
225 );
226 }