@@ -3090,6 +3090,87 @@ describe('ReactHooksWithNoopRenderer', () => {
3090
3090
} ) ,
3091
3091
) . toThrow ( 'is not a function' ) ;
3092
3092
} ) ;
3093
+
3094
+ it ( 'warns when setState is called from insertion effect setup' , ( ) => {
3095
+ function App ( props ) {
3096
+ const [ , setX ] = useState ( 0 ) ;
3097
+ useInsertionEffect ( ( ) => {
3098
+ setX ( 1 ) ;
3099
+ if ( props . throw ) {
3100
+ throw Error ( 'No' ) ;
3101
+ }
3102
+ } , [ props . throw ] ) ;
3103
+ return null ;
3104
+ }
3105
+
3106
+ const root = ReactNoop . createRoot ( ) ;
3107
+ expect ( ( ) =>
3108
+ act ( ( ) => {
3109
+ root . render ( < App /> ) ;
3110
+ } ) ,
3111
+ ) . toErrorDev ( [ 'Warning: useInsertionEffect must not schedule updates.' ] ) ;
3112
+
3113
+ expect ( ( ) => {
3114
+ act ( ( ) => {
3115
+ root . render ( < App throw = { true } /> ) ;
3116
+ } ) ;
3117
+ } ) . toThrow ( 'No' ) ;
3118
+
3119
+ // Should not warn for regular effects after throw.
3120
+ function NotInsertion ( ) {
3121
+ const [ , setX ] = useState ( 0 ) ;
3122
+ useEffect ( ( ) => {
3123
+ setX ( 1 ) ;
3124
+ } , [ ] ) ;
3125
+ return null ;
3126
+ }
3127
+ act ( ( ) => {
3128
+ root . render ( < NotInsertion /> ) ;
3129
+ } ) ;
3130
+ } ) ;
3131
+
3132
+ it ( 'warns when setState is called from insertion effect cleanup' , ( ) => {
3133
+ function App ( props ) {
3134
+ const [ , setX ] = useState ( 0 ) ;
3135
+ useInsertionEffect ( ( ) => {
3136
+ if ( props . throw ) {
3137
+ throw Error ( 'No' ) ;
3138
+ }
3139
+ return ( ) => {
3140
+ setX ( 1 ) ;
3141
+ } ;
3142
+ } , [ props . throw , props . foo ] ) ;
3143
+ return null ;
3144
+ }
3145
+
3146
+ const root = ReactNoop . createRoot ( ) ;
3147
+ act ( ( ) => {
3148
+ root . render ( < App foo = "hello" /> ) ;
3149
+ } ) ;
3150
+ expect ( ( ) => {
3151
+ act ( ( ) => {
3152
+ root . render ( < App foo = "goodbye" /> ) ;
3153
+ } ) ;
3154
+ } ) . toErrorDev ( [ 'Warning: useInsertionEffect must not schedule updates.' ] ) ;
3155
+
3156
+ expect ( ( ) => {
3157
+ act ( ( ) => {
3158
+ root . render ( < App throw = { true } /> ) ;
3159
+ } ) ;
3160
+ } ) . toThrow ( 'No' ) ;
3161
+
3162
+ // Should not warn for regular effects after throw.
3163
+ function NotInsertion ( ) {
3164
+ const [ , setX ] = useState ( 0 ) ;
3165
+ useEffect ( ( ) => {
3166
+ setX ( 1 ) ;
3167
+ } , [ ] ) ;
3168
+ return null ;
3169
+ }
3170
+ act ( ( ) => {
3171
+ root . render ( < NotInsertion /> ) ;
3172
+ } ) ;
3173
+ } ) ;
3093
3174
} ) ;
3094
3175
3095
3176
describe ( 'useLayoutEffect' , ( ) => {
0 commit comments