@@ -818,4 +818,93 @@ describe('Shared useSyncExternalStore behavior (shim and built-in)', () => {
818
818
'Sibling: 1' ,
819
819
] ) ;
820
820
} ) ;
821
+
822
+ describe ( 'selector and isEqual error handling in extra' , ( ) => {
823
+ let ErrorBoundary ;
824
+ beforeAll ( ( ) => {
825
+ spyOnDev ( console , 'warn' ) ;
826
+ ErrorBoundary = class extends React . Component {
827
+ state = { error : null } ;
828
+ static getDerivedStateFromError ( error ) {
829
+ return { error} ;
830
+ }
831
+ render ( ) {
832
+ if ( this . state . error ) {
833
+ return < Text text = { this . state . error . message } /> ;
834
+ }
835
+ return this . props . children ;
836
+ }
837
+ } ;
838
+ } ) ;
839
+
840
+ it ( 'selector can throw on update' , async ( ) => {
841
+ const store = createExternalStore ( { a : 'a' } ) ;
842
+ const selector = state => state . a . toUpperCase ( ) ;
843
+
844
+ function App ( ) {
845
+ const a = useSyncExternalStoreExtra (
846
+ store . subscribe ,
847
+ store . getState ,
848
+ null ,
849
+ selector ,
850
+ ) ;
851
+ return < Text text = { a } /> ;
852
+ }
853
+
854
+ const container = document . createElement ( 'div' ) ;
855
+ const root = createRoot ( container ) ;
856
+ await act ( ( ) =>
857
+ root . render (
858
+ < ErrorBoundary >
859
+ < App />
860
+ </ ErrorBoundary > ,
861
+ ) ,
862
+ ) ;
863
+
864
+ expect ( container . textContent ) . toEqual ( 'A' ) ;
865
+
866
+ await act ( ( ) => {
867
+ store . set ( { } ) ;
868
+ } ) ;
869
+ expect ( container . textContent ) . toEqual (
870
+ "Cannot read property 'toUpperCase' of undefined" ,
871
+ ) ;
872
+ } ) ;
873
+
874
+ it ( 'isEqual can throw on update' , async ( ) => {
875
+ const store = createExternalStore ( { a : 'A' } ) ;
876
+ const selector = state => state . a ;
877
+ const isEqual = ( left , right ) => left . a . trim ( ) === right . a . trim ( ) ;
878
+
879
+ function App ( ) {
880
+ const a = useSyncExternalStoreExtra (
881
+ store . subscribe ,
882
+ store . getState ,
883
+ null ,
884
+ selector ,
885
+ isEqual ,
886
+ ) ;
887
+ return < Text text = { a } /> ;
888
+ }
889
+
890
+ const container = document . createElement ( 'div' ) ;
891
+ const root = createRoot ( container ) ;
892
+ await act ( ( ) =>
893
+ root . render (
894
+ < ErrorBoundary >
895
+ < App />
896
+ </ ErrorBoundary > ,
897
+ ) ,
898
+ ) ;
899
+
900
+ expect ( container . textContent ) . toEqual ( 'A' ) ;
901
+
902
+ await act ( ( ) => {
903
+ store . set ( { } ) ;
904
+ } ) ;
905
+ expect ( container . textContent ) . toEqual (
906
+ "Cannot read property 'trim' of undefined" ,
907
+ ) ;
908
+ } ) ;
909
+ } ) ;
821
910
} ) ;
0 commit comments