@samitouri / QOS-React / commits / a08ae9f147

Listen to onScroll during hydration (#19803)

Dan Abramov committed Sep 10, 2020 at 11:00 UTC a08ae9f147a716520a089055e2dec8f5397a4b0f
2 files changed +108
packages/react-dom/src/__tests__/ReactDOMEventListener-test.js
+106
@@ -12,11 +12,13 @@
12 describe('ReactDOMEventListener', () => {
13 let React;
14 let ReactDOM;
15 + let ReactDOMServer;
16
17 beforeEach(() => {
18 jest.resetModules();
19 React = require('react');
20 ReactDOM = require('react-dom');
21 + ReactDOMServer = require('react-dom/server');
22 });
23
24 describe('Propagation', () => {
@@ -797,4 +799,108 @@ describe('ReactDOMEventListener', () => {
799 document.body.removeChild(container);
800 }
801 });
802 +
803 + it('should subscribe to scroll during updates', () => {
804 + const container = document.createElement('div');
805 + const ref = React.createRef();
806 + const log = [];
807 + const onScroll = jest.fn(e =>
808 + log.push(['bubble', e.currentTarget.className]),
809 + );
810 + const onScrollCapture = jest.fn(e =>
811 + log.push(['capture', e.currentTarget.className]),
812 + );
813 + document.body.appendChild(container);
814 + try {
815 + ReactDOM.render(
816 + <div>
817 + <div>
818 + <div />
819 + </div>
820 + </div>,
821 + container,
822 + );
823 + ReactDOM.render(
824 + <div
825 + className="grand"
826 + onScroll={onScroll}
827 + onScrollCapture={onScrollCapture}>
828 + <div
829 + className="parent"
830 + onScroll={onScroll}
831 + onScrollCapture={onScrollCapture}>
832 + <div
833 + className="child"
834 + onScroll={onScroll}
835 + onScrollCapture={onScrollCapture}
836 + ref={ref}
837 + />
838 + </div>
839 + </div>,
840 + container,
841 + );
842 + ref.current.dispatchEvent(
843 + new Event('scroll', {
844 + bubbles: false,
845 + }),
846 + );
847 + expect(log).toEqual([
848 + ['capture', 'grand'],
849 + ['capture', 'parent'],
850 + ['capture', 'child'],
851 + ['bubble', 'child'],
852 + ]);
853 + } finally {
854 + document.body.removeChild(container);
855 + }
856 + });
857 +
858 + // Regression test.
859 + it('should subscribe to scroll during hydration', () => {
860 + const container = document.createElement('div');
861 + const ref = React.createRef();
862 + const log = [];
863 + const onScroll = jest.fn(e =>
864 + log.push(['bubble', e.currentTarget.className]),
865 + );
866 + const onScrollCapture = jest.fn(e =>
867 + log.push(['capture', e.currentTarget.className]),
868 + );
869 + const tree = (
870 + <div
871 + className="grand"
872 + onScroll={onScroll}
873 + onScrollCapture={onScrollCapture}>
874 + <div
875 + className="parent"
876 + onScroll={onScroll}
877 + onScrollCapture={onScrollCapture}>
878 + <div
879 + className="child"
880 + onScroll={onScroll}
881 + onScrollCapture={onScrollCapture}
882 + ref={ref}
883 + />
884 + </div>
885 + </div>
886 + );
887 + document.body.appendChild(container);
888 + try {
889 + container.innerHTML = ReactDOMServer.renderToString(tree);
890 + ReactDOM.hydrate(tree, container);
891 + ref.current.dispatchEvent(
892 + new Event('scroll', {
893 + bubbles: false,
894 + }),
895 + );
896 + expect(log).toEqual([
897 + ['capture', 'grand'],
898 + ['capture', 'parent'],
899 + ['capture', 'child'],
900 + ['bubble', 'child'],
901 + ]);
902 + } finally {
903 + document.body.removeChild(container);
904 + }
905 + });
906 });
packages/react-dom/src/client/ReactDOMComponent.js
+2
@@ -1086,6 +1086,8 @@ export function diffHydratedProperties(
1086 }
1087 if (!enableEagerRootListeners) {
1088 ensureListeningTo(rootContainerElement, propKey, domElement);
1089 + } else if (propKey === 'onScroll') {
1090 + listenToNonDelegatedEvent('scroll', domElement);
1091 }
1092 }
1093 } else if (