Add regression test for #19269 (#19282)
Dan Abramov committed
Jul 8, 2020 at 20:48 UTC
e0e6b9c036abde428d3130738604fd5abb67aa8f
1 file changed
+83
packages/react-dom/src/__tests__/ReactDOMServerPartialHydration-test.internal.js
+83
@@ -2897,6 +2897,89 @@ describe('ReactDOMServerPartialHydration', () => {
2897
expect(ref.current).not.toBe(null);
2898
});
2899
2900
+ // @gate experimental
2901
+ it('regression test: does not overfire non-bubbling browser events', async () => {
2902
+ let suspend = false;
2903
+ let resolve;
2904
+ const promise = new Promise(resolvePromise => (resolve = resolvePromise));
2905
+
2906
+ function Sibling({text}) {
2907
+ if (suspend) {
2908
+ throw promise;
2909
+ } else {
2910
+ return 'Hello';
2911
+ }
2912
+ }
2913
+
2914
+ let submits = 0;
2915
+
2916
+ function Form() {
2917
+ const [submitted, setSubmitted] = React.useState(false);
2918
+ if (submitted) {
2919
+ return null;
2920
+ }
2921
+ return (
2922
+ <form
2923
+ onSubmit={() => {
2924
+ setSubmitted(true);
2925
+ submits++;
2926
+ }}>
2927
+ Click me
2928
+ </form>
2929
+ );
2930
+ }
2931
+
2932
+ function App() {
2933
+ return (
2934
+ <div>
2935
+ <Suspense fallback="Loading...">
2936
+ <Form />
2937
+ <Sibling />
2938
+ </Suspense>
2939
+ </div>
2940
+ );
2941
+ }
2942
+
2943
+ suspend = false;
2944
+ const finalHTML = ReactDOMServer.renderToString(<App />);
2945
+ const container = document.createElement('div');
2946
+ container.innerHTML = finalHTML;
2947
+
2948
+ // We need this to be in the document since we'll dispatch events on it.
2949
+ document.body.appendChild(container);
2950
+
2951
+ const form = container.getElementsByTagName('form')[0];
2952
+
2953
+ // On the client we don't have all data yet but we want to start
2954
+ // hydrating anyway.
2955
+ suspend = true;
2956
+ const root = ReactDOM.createRoot(container, {hydrate: true});
2957
+ root.render(<App />);
2958
+ Scheduler.unstable_flushAll();
2959
+ jest.runAllTimers();
2960
+
2961
+ expect(container.textContent).toBe('Click meHello');
2962
+
2963
+ // We're now partially hydrated.
2964
+ form.dispatchEvent(
2965
+ new Event('submit', {
2966
+ bubbles: true,
2967
+ }),
2968
+ );
2969
+ expect(submits).toBe(0);
2970
+
2971
+ // Resolving the promise so that rendering can complete.
2972
+ suspend = false;
2973
+ resolve();
2974
+ await promise;
2975
+
2976
+ Scheduler.unstable_flushAll();
2977
+ jest.runAllTimers();
2978
+ expect(submits).toBe(1);
2979
+ expect(container.textContent).toBe('Hello');
2980
+ document.body.removeChild(container);
2981
+ });
2982
+
2983
// This test fails, in both forks. Without a boundary, the deferred tree won't
2984
// re-enter hydration mode. It doesn't come up in practice because there's
2985
// always a parent Suspense boundary. But it's still a bug. Leaving for a