mirror of
https://github.com/zhigang1992/react-navigation.git
synced 2026-03-06 17:34:59 +08:00
fix: fix incorrect state change events in independent nested container
fixes #9080
This commit is contained in:
@@ -8,9 +8,11 @@ import {
|
||||
NavigationAction,
|
||||
} from '@react-navigation/routers';
|
||||
import EnsureSingleNavigator from './EnsureSingleNavigator';
|
||||
import UnhandledActionContext from './UnhandledActionContext';
|
||||
import NavigationBuilderContext from './NavigationBuilderContext';
|
||||
import NavigationStateContext from './NavigationStateContext';
|
||||
import UnhandledActionContext from './UnhandledActionContext';
|
||||
import NavigationRouteContext from './NavigationRouteContext';
|
||||
import NavigationContext from './NavigationContext';
|
||||
import { ScheduleUpdateContext } from './useScheduleUpdate';
|
||||
import useChildListeners from './useChildListeners';
|
||||
import useKeyedChildListeners from './useKeyedChildListeners';
|
||||
@@ -397,7 +399,7 @@ const BaseNavigationContainer = React.forwardRef(
|
||||
[]
|
||||
);
|
||||
|
||||
return (
|
||||
let element = (
|
||||
<ScheduleUpdateContext.Provider value={scheduleContext}>
|
||||
<NavigationBuilderContext.Provider value={builderContext}>
|
||||
<NavigationStateContext.Provider value={context}>
|
||||
@@ -410,6 +412,19 @@ const BaseNavigationContainer = React.forwardRef(
|
||||
</NavigationBuilderContext.Provider>
|
||||
</ScheduleUpdateContext.Provider>
|
||||
);
|
||||
|
||||
if (independent) {
|
||||
// We need to clear any existing contexts for nested independent container to work correctly
|
||||
element = (
|
||||
<NavigationRouteContext.Provider value={undefined}>
|
||||
<NavigationContext.Provider value={undefined}>
|
||||
{element}
|
||||
</NavigationContext.Provider>
|
||||
</NavigationRouteContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
return element;
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@@ -757,3 +757,67 @@ it('invokes the unhandled action listener with the unhandled action', () => {
|
||||
type: 'NAVIGATE',
|
||||
});
|
||||
});
|
||||
|
||||
it('works with state change events in independent nested container', () => {
|
||||
const TestNavigator = (props: any) => {
|
||||
const { state, descriptors } = useNavigationBuilder(MockRouter, props);
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
{state.routes.map((route) => descriptors[route.key].render())}
|
||||
</React.Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
const ref = React.createRef<NavigationContainerRef>();
|
||||
|
||||
const onStateChange = jest.fn();
|
||||
|
||||
render(
|
||||
<BaseNavigationContainer>
|
||||
<TestNavigator>
|
||||
<Screen name="foo">
|
||||
{() => (
|
||||
<BaseNavigationContainer
|
||||
independent
|
||||
ref={ref}
|
||||
onStateChange={onStateChange}
|
||||
>
|
||||
<TestNavigator>
|
||||
<Screen name="qux">{() => null}</Screen>
|
||||
<Screen name="lex">{() => null}</Screen>
|
||||
</TestNavigator>
|
||||
</BaseNavigationContainer>
|
||||
)}
|
||||
</Screen>
|
||||
<Screen name="bar">{() => null}</Screen>
|
||||
</TestNavigator>
|
||||
</BaseNavigationContainer>
|
||||
);
|
||||
|
||||
act(() => ref.current?.navigate('lex'));
|
||||
|
||||
expect(onStateChange).toBeCalledWith({
|
||||
index: 1,
|
||||
key: '15',
|
||||
routeNames: ['qux', 'lex'],
|
||||
routes: [
|
||||
{ key: 'qux', name: 'qux' },
|
||||
{ key: 'lex', name: 'lex' },
|
||||
],
|
||||
stale: false,
|
||||
type: 'test',
|
||||
});
|
||||
|
||||
expect(ref.current?.getRootState()).toEqual({
|
||||
index: 1,
|
||||
key: '15',
|
||||
routeNames: ['qux', 'lex'],
|
||||
routes: [
|
||||
{ key: 'qux', name: 'qux' },
|
||||
{ key: 'lex', name: 'lex' },
|
||||
],
|
||||
stale: false,
|
||||
type: 'test',
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user