@@ -158,6 +158,77 @@ describe("navigation blocking with useBlocker", () => {
158158 act ( ( ) => root . unmount ( ) ) ;
159159 } ) ;
160160
161+ it ( "handles reused blocker in a layout route" , async ( ) => {
162+ router = createMemoryRouter ( [
163+ {
164+ Component ( ) {
165+ let blocker = useBlocker ( true ) ;
166+ return (
167+ < div >
168+ < Link to = "/one" > /one</ Link >
169+ < Link to = "/two" > /two</ Link >
170+ < Outlet />
171+ < p > { blocker . state } </ p >
172+ { blocker . state === "blocked" ? (
173+ < button onClick = { ( ) => blocker . proceed ?.( ) } > Proceed</ button >
174+ ) : null }
175+ </ div >
176+ ) ;
177+ } ,
178+ children : [
179+ {
180+ path : "/" ,
181+ element : < h1 > Home</ h1 > ,
182+ } ,
183+ {
184+ path : "/one" ,
185+ element : < h1 > One</ h1 > ,
186+ } ,
187+ {
188+ path : "/two" ,
189+ element : < h1 > Two</ h1 > ,
190+ } ,
191+ ] ,
192+ } ,
193+ ] ) ;
194+
195+ act ( ( ) => {
196+ root = ReactDOM . createRoot ( node ) ;
197+ root . render ( < RouterProvider router = { router } /> ) ;
198+ } ) ;
199+
200+ // Start on /
201+ expect ( node . querySelector ( "h1" ) ?. textContent ) . toBe ( "Home" ) ;
202+ expect ( node . querySelector ( "p" ) ?. textContent ) . toBe ( "unblocked" ) ;
203+ expect ( node . querySelector ( "button" ) ) . toBeNull ( ) ;
204+
205+ // Blocked navigation to /one
206+ act ( ( ) => click ( node . querySelector ( "a[href='/one']" ) ) ) ;
207+ expect ( node . querySelector ( "h1" ) ?. textContent ) . toBe ( "Home" ) ;
208+ expect ( node . querySelector ( "p" ) ?. textContent ) . toBe ( "blocked" ) ;
209+ expect ( node . querySelector ( "button" ) ?. textContent ) . toBe ( "Proceed" ) ;
210+
211+ // Proceed to /one
212+ act ( ( ) => click ( node . querySelector ( "button" ) ) ) ;
213+ expect ( node . querySelector ( "h1" ) ?. textContent ) . toBe ( "One" ) ;
214+ expect ( node . querySelector ( "p" ) ?. textContent ) . toBe ( "unblocked" ) ;
215+ expect ( node . querySelector ( "button" ) ) . toBeNull ( ) ;
216+
217+ // Blocked navigation to /two
218+ act ( ( ) => click ( node . querySelector ( "a[href='/two']" ) ) ) ;
219+ expect ( node . querySelector ( "h1" ) ?. textContent ) . toBe ( "One" ) ;
220+ expect ( node . querySelector ( "p" ) ?. textContent ) . toBe ( "blocked" ) ;
221+ expect ( node . querySelector ( "button" ) ?. textContent ) . toBe ( "Proceed" ) ;
222+
223+ // Proceed to /two
224+ act ( ( ) => click ( node . querySelector ( "button" ) ) ) ;
225+ expect ( node . querySelector ( "h1" ) ?. textContent ) . toBe ( "Two" ) ;
226+ expect ( node . querySelector ( "p" ) ?. textContent ) . toBe ( "unblocked" ) ;
227+ expect ( node . querySelector ( "button" ) ) . toBeNull ( ) ;
228+
229+ act ( ( ) => root . unmount ( ) ) ;
230+ } ) ;
231+
161232 describe ( "on <Link> navigation" , ( ) => {
162233 describe ( "blocker returns false" , ( ) => {
163234 beforeEach ( ( ) => {
0 commit comments