mirror of
https://github.com/zhigang1992/react-navigation.git
synced 2026-02-10 17:23:42 +08:00
93 lines
2.5 KiB
TypeScript
93 lines
2.5 KiB
TypeScript
import * as React from 'react';
|
|
import { NavigationStateContext } from './NavigationContainer';
|
|
import StaticContainer from './StaticContainer';
|
|
import {
|
|
Route,
|
|
NavigationState,
|
|
NavigationHelpers,
|
|
RouteConfig,
|
|
} from './types';
|
|
import EnsureSingleNavigator from './EnsureSingleNavigator';
|
|
|
|
type Props = {
|
|
screen: RouteConfig;
|
|
navigation: NavigationHelpers;
|
|
route: Route & { state?: NavigationState };
|
|
getState: () => NavigationState;
|
|
setState: (state: NavigationState) => void;
|
|
};
|
|
|
|
export default function SceneView(props: Props) {
|
|
const { screen, route, navigation: helpers, getState, setState } = props;
|
|
|
|
const navigation = React.useMemo(
|
|
() => ({
|
|
...helpers,
|
|
setParams: (params: object) => {
|
|
const state = getState();
|
|
|
|
setState({
|
|
...state,
|
|
routes: state.routes.map(r =>
|
|
r.key === route.key
|
|
? { ...r, params: { ...r.params, ...params } }
|
|
: r
|
|
),
|
|
});
|
|
},
|
|
}),
|
|
[getState, helpers, route.key, setState]
|
|
);
|
|
|
|
const getCurrentState = React.useCallback(() => {
|
|
const state = getState();
|
|
const currentRoute = state.routes.find(r => r.key === route.key);
|
|
|
|
return currentRoute ? currentRoute.state : undefined;
|
|
}, [getState, route.key]);
|
|
|
|
const setCurrentState = React.useCallback(
|
|
(child: NavigationState | undefined) => {
|
|
const state = getState();
|
|
|
|
setState({
|
|
...state,
|
|
routes: state.routes.map(r =>
|
|
r.key === route.key ? { ...r, state: child } : r
|
|
),
|
|
});
|
|
},
|
|
[getState, route, setState]
|
|
);
|
|
|
|
const context = React.useMemo(
|
|
() => ({
|
|
state: route.state,
|
|
getState: getCurrentState,
|
|
setState: setCurrentState,
|
|
key: route.key,
|
|
}),
|
|
[getCurrentState, route.key, route.state, setCurrentState]
|
|
);
|
|
|
|
return (
|
|
<NavigationStateContext.Provider value={context}>
|
|
<EnsureSingleNavigator>
|
|
<StaticContainer
|
|
name={screen.name}
|
|
// @ts-ignore
|
|
render={screen.component || screen.children}
|
|
navigation={navigation}
|
|
route={route}
|
|
>
|
|
{'component' in screen && screen.component !== undefined ? (
|
|
<screen.component navigation={navigation} route={route} />
|
|
) : 'children' in screen && screen.children !== undefined ? (
|
|
screen.children({ navigation, route })
|
|
) : null}
|
|
</StaticContainer>
|
|
</EnsureSingleNavigator>
|
|
</NavigationStateContext.Provider>
|
|
);
|
|
}
|