mirror of
https://github.com/zhigang1992/react-navigation.git
synced 2026-01-13 09:30:30 +08:00
Add withNavigation HOC (#137)
This commit is contained in:
committed by
Satyajit Sahoo
parent
d2fc150f69
commit
aead8ff9fb
17
docs/api/withNavigation.md
Normal file
17
docs/api/withNavigation.md
Normal file
@@ -0,0 +1,17 @@
|
||||
|
||||
# withNavigation
|
||||
|
||||
[`withNavigation`](/src/views/withNavigation.js) is a Higher Order Component which passes the `navigation` prop into wrapped Component. It's useful when you cannnot pass the `navigation` prop into into the component directly, or don't want to pass it in case of a deeply nested child.
|
||||
|
||||
## Example
|
||||
|
||||
```js
|
||||
import { Button } 'react-native';
|
||||
import { withNavigation } from 'react-navigation';
|
||||
|
||||
const MyComponent = ({ to, navigation }) => (
|
||||
<Button title={`navigate to ${to}`} onPress={() => navigation.navigate(to)} />
|
||||
);
|
||||
|
||||
const MyComponentWithNavigation = withNavigation(MyComponent);
|
||||
```
|
||||
@@ -19,6 +19,7 @@ import ModalStack from './ModalStack';
|
||||
import StacksInTabs from './StacksInTabs';
|
||||
import SimpleStack from './SimpleStack';
|
||||
import SimpleTabs from './SimpleTabs';
|
||||
import WithNavigation from './WithNavigation';
|
||||
|
||||
const ExampleRoutes = {
|
||||
SimpleStack: {
|
||||
@@ -63,6 +64,11 @@ const ExampleRoutes = {
|
||||
screen: SimpleTabs,
|
||||
path: 'settings',
|
||||
},
|
||||
WithNavigation: {
|
||||
name: 'withNavigation HOC',
|
||||
description: 'Navigating using `withNavigation` HOC',
|
||||
screen: WithNavigation,
|
||||
},
|
||||
};
|
||||
|
||||
const MainScreen = ({ navigation }) => (
|
||||
|
||||
33
examples/NavigationPlayground/js/WithNavigation.js
Normal file
33
examples/NavigationPlayground/js/WithNavigation.js
Normal file
@@ -0,0 +1,33 @@
|
||||
/* @flow */
|
||||
|
||||
import React from 'react';
|
||||
import {
|
||||
View,
|
||||
Text,
|
||||
Button,
|
||||
} from 'react-native';
|
||||
import { TabNavigator, withNavigation } from 'react-navigation';
|
||||
|
||||
const ButtonWithNavigation = withNavigation(({ navigation, to, ...rest }) => (
|
||||
<Button {...rest} onPress={() => navigation.navigate(to)} />
|
||||
));
|
||||
|
||||
const createTabWithNavigationButtons = (tabName: string, links: Array<string>) => {
|
||||
const Tab = () => (
|
||||
<View>
|
||||
<Text>This is tab: {tabName}</Text>
|
||||
<Text>You can navigate to:</Text>
|
||||
{links.map(link => (
|
||||
<ButtonWithNavigation key={link} to={link} title={link} />
|
||||
))}
|
||||
</View>
|
||||
);
|
||||
|
||||
return Tab;
|
||||
};
|
||||
|
||||
export default TabNavigator({
|
||||
Tab1: { screen: createTabWithNavigationButtons('Tab1', ['Tab2', 'Tab3']) },
|
||||
Tab2: { screen: createTabWithNavigationButtons('Tab2', ['Tab3', 'Tab1']) },
|
||||
Tab3: { screen: createTabWithNavigationButtons('Tab2', ['Tab2', 'Tab1']) },
|
||||
});
|
||||
@@ -65,6 +65,7 @@
|
||||
"dependencies": {
|
||||
"clamp": "^1.0.1",
|
||||
"fbjs": "^0.8.5",
|
||||
"hoist-non-react-statics": "^1.2.0",
|
||||
"path-to-regexp": "^1.7.0",
|
||||
"react-native-drawer-layout": "^1.1.0",
|
||||
"react-native-tab-view": "^0.0.54"
|
||||
|
||||
@@ -441,3 +441,7 @@ export type NavigationSceneRenderer = (
|
||||
export type NavigationStyleInterpolator = (
|
||||
props: NavigationSceneRendererProps,
|
||||
) => Object;
|
||||
|
||||
export type ContextWithNavigation = {
|
||||
navigation: NavigationScreenProp<NavigationState, NavigationAction>;
|
||||
};
|
||||
|
||||
3
src/react-navigation.js
vendored
3
src/react-navigation.js
vendored
@@ -26,4 +26,7 @@ module.exports = {
|
||||
get CardStack() { return require('./views/CardStack').default; },
|
||||
get DrawerView() { return require('./views/Drawer/DrawerView').default; },
|
||||
get TabView() { return require('./views/TabView/TabView').default; },
|
||||
|
||||
// HOCs
|
||||
get withNavigation() { return require('./views/withNavigation').default; },
|
||||
};
|
||||
|
||||
@@ -6,6 +6,7 @@ import type {
|
||||
NavigationScreenProp,
|
||||
NavigationState,
|
||||
NavigationAction,
|
||||
ContextWithNavigation,
|
||||
} from '../TypeDefinition';
|
||||
|
||||
type Props = {
|
||||
@@ -15,8 +16,19 @@ type Props = {
|
||||
};
|
||||
|
||||
export default class SceneView extends PureComponent<void, Props, void> {
|
||||
|
||||
static childContextTypes = {
|
||||
navigation: React.PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
props: Props;
|
||||
|
||||
getChildContext(): ContextWithNavigation {
|
||||
return {
|
||||
navigation: this.props.navigation,
|
||||
};
|
||||
}
|
||||
|
||||
render() {
|
||||
const { screenProps, navigation, component: Component } = this.props;
|
||||
return <Component {...screenProps} navigation={navigation} />;
|
||||
|
||||
20
src/views/withNavigation.js
Normal file
20
src/views/withNavigation.js
Normal file
@@ -0,0 +1,20 @@
|
||||
/* @flow */
|
||||
|
||||
import React from 'react';
|
||||
import hoistStatics from 'hoist-non-react-statics';
|
||||
|
||||
import { ContextWithNavigation } from '../TypeDefinition';
|
||||
|
||||
export default function withNavigation(Component: ReactClass<T>) {
|
||||
const componentWithNavigation = (props: T, { navigation }: ContextWithNavigation) => (
|
||||
<Component {...props} navigation={navigation} />
|
||||
);
|
||||
|
||||
componentWithNavigation.displayName = `withNavigation(${Component.displayName || Component.name})`;
|
||||
|
||||
componentWithNavigation.contextTypes = {
|
||||
navigation: React.PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
return hoistStatics(componentWithNavigation, Component);
|
||||
}
|
||||
@@ -2415,6 +2415,10 @@ hoek@2.x.x:
|
||||
version "2.16.3"
|
||||
resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed"
|
||||
|
||||
hoist-non-react-statics@^1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-1.2.0.tgz#aa448cf0986d55cc40773b17174b7dd066cb7cfb"
|
||||
|
||||
home-or-tmp@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8"
|
||||
@@ -3361,13 +3365,13 @@ mime-db@~1.23.0:
|
||||
version "1.23.0"
|
||||
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.23.0.tgz#a31b4070adaea27d732ea333740a64d0ec9a6659"
|
||||
|
||||
mime-types@2.1.11, mime-types@~2.1.7:
|
||||
mime-types@2.1.11, mime-types@~2.1.7, mime-types@~2.1.9:
|
||||
version "2.1.11"
|
||||
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.11.tgz#c259c471bda808a85d6cd193b430a5fae4473b3c"
|
||||
dependencies:
|
||||
mime-db "~1.23.0"
|
||||
|
||||
mime-types@^2.1.12, mime-types@~2.1.11, mime-types@~2.1.13, mime-types@~2.1.6, mime-types@~2.1.9:
|
||||
mime-types@^2.1.12, mime-types@~2.1.11, mime-types@~2.1.13, mime-types@~2.1.6:
|
||||
version "2.1.14"
|
||||
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.14.tgz#f7ef7d97583fcaf3b7d282b6f8b5679dab1e94ee"
|
||||
dependencies:
|
||||
|
||||
Reference in New Issue
Block a user