mirror of
https://github.com/zhigang1992/react-navigation.git
synced 2026-04-24 04:25:34 +08:00
feat: add basic nesting example
This commit is contained in:
@@ -10,6 +10,7 @@ import {
|
||||
|
||||
type Props = {
|
||||
initialRouteName?: string;
|
||||
navigation?: NavigationProp;
|
||||
children: React.ReactElement[];
|
||||
};
|
||||
|
||||
@@ -42,6 +43,7 @@ const StackRouter = {
|
||||
switch (action.type) {
|
||||
case 'PUSH':
|
||||
return {
|
||||
...state,
|
||||
index: state.index + 1,
|
||||
routes: [
|
||||
...state.routes,
|
||||
@@ -54,6 +56,7 @@ const StackRouter = {
|
||||
case 'POP':
|
||||
return state.index > 0
|
||||
? {
|
||||
...state,
|
||||
index: state.index - 1,
|
||||
routes: state.routes.slice(0, state.routes.length - 1),
|
||||
}
|
||||
@@ -73,13 +76,10 @@ const StackRouter = {
|
||||
},
|
||||
};
|
||||
|
||||
export default function StackNavigator({ initialRouteName, children }: Props) {
|
||||
export default function StackNavigator(props: Props) {
|
||||
// The `navigation` object contains the navigation state and some helpers (e.g. push, pop)
|
||||
// The `descriptors` object contains `navigation` objects for children routes and helper for rendering a screen
|
||||
const { navigation, descriptors } = useNavigationBuilder(StackRouter, {
|
||||
initialRouteName,
|
||||
children,
|
||||
});
|
||||
const { navigation, descriptors } = useNavigationBuilder(StackRouter, props);
|
||||
|
||||
return (
|
||||
<div style={{ position: 'relative' }}>
|
||||
|
||||
82
example/TabNavigator.tsx
Normal file
82
example/TabNavigator.tsx
Normal file
@@ -0,0 +1,82 @@
|
||||
/* eslint-disable react-native/no-inline-styles */
|
||||
|
||||
import * as React from 'react';
|
||||
import shortid from 'shortid';
|
||||
import {
|
||||
useNavigationBuilder,
|
||||
NavigationState,
|
||||
NavigationProp,
|
||||
} from '../src/index';
|
||||
|
||||
type Props = {
|
||||
initialRouteName?: string;
|
||||
navigation?: NavigationProp;
|
||||
children: React.ReactElement[];
|
||||
};
|
||||
|
||||
type Action = {
|
||||
type: 'JUMP_TO';
|
||||
payload: { name: string };
|
||||
};
|
||||
|
||||
export type TabNavigationProp = NavigationProp<typeof TabRouter>;
|
||||
|
||||
const TabRouter = {
|
||||
getInitialState(
|
||||
routeNames: string[],
|
||||
{ initialRouteName = routeNames[0] }: { initialRouteName?: string }
|
||||
) {
|
||||
const index = routeNames.indexOf(initialRouteName);
|
||||
|
||||
return {
|
||||
index,
|
||||
routes: routeNames.map(name => ({
|
||||
name,
|
||||
key: `${name}-${shortid()}`,
|
||||
})),
|
||||
};
|
||||
},
|
||||
|
||||
reduce(state: NavigationState, action: Action) {
|
||||
switch (action.type) {
|
||||
case 'JUMP_TO':
|
||||
return {
|
||||
...state,
|
||||
index: state.routes.findIndex(
|
||||
route => route.name === action.payload.name
|
||||
),
|
||||
};
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
},
|
||||
|
||||
actions: {
|
||||
jumpTo(name: string): Action {
|
||||
return { type: 'JUMP_TO', payload: { name } };
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default function TabNavigator(props: Props) {
|
||||
// The `navigation` object contains the navigation state and some helpers (e.g. push, pop)
|
||||
// The `descriptors` object contains `navigation` objects for children routes and helper for rendering a screen
|
||||
const { navigation, descriptors } = useNavigationBuilder(TabRouter, props);
|
||||
|
||||
return (
|
||||
<div style={{ display: 'flex', flexDirection: 'row' }}>
|
||||
{navigation.state.routes.map((route, i, self) => (
|
||||
<div
|
||||
key={route.key}
|
||||
style={{
|
||||
width: `${100 / self.length}%`,
|
||||
backgroundColor: i === navigation.state.index ? 'tomato' : 'white',
|
||||
border: '1px solid black',
|
||||
}}
|
||||
>
|
||||
{descriptors[route.name].render()}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -3,6 +3,7 @@ import * as React from 'react';
|
||||
import { render } from 'react-dom';
|
||||
import { NavigationContainer, Screen } from '../src';
|
||||
import StackNavigator, { StackNavigationProp } from './StackNavigator';
|
||||
import TabNavigator, { TabNavigationProp } from './TabNavigator';
|
||||
|
||||
const First = ({ navigation }: { navigation: StackNavigationProp }) => (
|
||||
<div>
|
||||
@@ -10,6 +11,9 @@ const First = ({ navigation }: { navigation: StackNavigationProp }) => (
|
||||
<button type="button" onClick={() => navigation.push('second')}>
|
||||
Push second
|
||||
</button>
|
||||
<button type="button" onClick={() => navigation.push('third')}>
|
||||
Push third
|
||||
</button>
|
||||
<button type="button" onClick={() => navigation.pop()}>
|
||||
Go back
|
||||
</button>
|
||||
@@ -28,6 +32,44 @@ const Second = ({ navigation }: { navigation: StackNavigationProp }) => (
|
||||
</div>
|
||||
);
|
||||
|
||||
const Fourth = ({
|
||||
navigation,
|
||||
}: {
|
||||
navigation: TabNavigationProp & StackNavigationProp;
|
||||
}) => (
|
||||
<div>
|
||||
<h1>Fourth route</h1>
|
||||
<button type="button" onClick={() => navigation.jumpTo('fifth')}>
|
||||
Jump to fifth
|
||||
</button>
|
||||
<button type="button" onClick={() => navigation.push('first')}>
|
||||
Push first
|
||||
</button>
|
||||
<button type="button" onClick={() => navigation.pop()}>
|
||||
Go back
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
|
||||
const Fifth = ({
|
||||
navigation,
|
||||
}: {
|
||||
navigation: TabNavigationProp & StackNavigationProp;
|
||||
}) => (
|
||||
<div>
|
||||
<h1>Fifth route</h1>
|
||||
<button type="button" onClick={() => navigation.jumpTo('fourth')}>
|
||||
Jump to fourth
|
||||
</button>
|
||||
<button type="button" onClick={() => navigation.push('second')}>
|
||||
Push second
|
||||
</button>
|
||||
<button type="button" onClick={() => navigation.pop()}>
|
||||
Go back
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
|
||||
const routes =
|
||||
location.pathname !== '/'
|
||||
? location.pathname
|
||||
@@ -49,6 +91,14 @@ function App() {
|
||||
<StackNavigator>
|
||||
<Screen name="first" component={First} />
|
||||
<Screen name="second" component={Second} />
|
||||
<Screen name="third">
|
||||
{props => (
|
||||
<TabNavigator {...props}>
|
||||
<Screen name="fourth" component={Fourth} />
|
||||
<Screen name="fifth" component={Fifth} />
|
||||
</TabNavigator>
|
||||
)}
|
||||
</Screen>
|
||||
</StackNavigator>
|
||||
</NavigationContainer>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user