diff --git a/README.md b/README.md index 8b482219f..20ae225df 100644 --- a/README.md +++ b/README.md @@ -475,4 +475,4 @@ Sure it could be done using Redux, however it will require more coding and progr + GuavaPass.com ([iOS](https://itunes.apple.com/en/app/guavapass-one-pass-fitness/id1050491044?l=en&mt=8), Android) - offers convenient access to top classes at boutique fitness studios across Asia. ## Support -Thanks to all who submitted PRs to 2.x release. If you like the component and want to support it, feel free to donate any amount or help with issues. +Thanks to all who submitted PRs to 2.x release. If you like the component and want to support it, feel free to donate any amount or help with issues. \ No newline at end of file diff --git a/docs/API_CONFIGURATION.md b/docs/API_CONFIGURATION.md new file mode 100644 index 000000000..5f4741def --- /dev/null +++ b/docs/API_CONFIGURATION.md @@ -0,0 +1,100 @@ +# API and Configuration + +## Available imports +- `Router` +- `Scene` +- `Modal` +- `TabBar` +- `getInitialState` +- `Reducer` +- `DefaultRenderer` +- `Switch` +- `Actions` +- `NavBar` + +## Router: +| Property | Type | Default | Description | +|---------------|----------|--------------|----------------------------------------------------------------| +| reducer | `function` | | optional user-defined reducer for scenes, you may want to use it to intercept all actions and put your custom logic | +| createReducer | `function` | | function that returns a reducer function for {initialState, scenes} param, you may wrap Reducer(param) with your custom reducer, check Flux usage section below| +| other props | | | all properties that will be passed to all your scenes | +| children | | required (if no scenes property passed)| Scene root element | +| scenes | `object` | optional | scenes for Router created with Actions.create. This will allow to create all actions BEFORE React processing. If you don't need it you may pass Scene root element as children | +| getSceneStyle | `function` | optional | Optionally override the styles for NavigationCard's Animated.View rendering the scene. | + +## Scene: + +| Property | Type | Default | Description | +|-----------|--------|---------|--------------------------------------------| +| key | `string` | required | Will be used to call screen transition, for example, `Actions.name(params)`. Must be unique. | +| component | `React.Component` | semi-required | The `Component` to be displayed. Not required when defining a nested `Scene`, see example. If it is defined for 'container' scene, it will be used as custom container `renderer` | +| initial | `bool` | false | Set to `true` if this is the initial scene | +| type | `string` | 'push' or 'jump' | Defines how the new screen is added to the navigator stack. One of `push`, `jump`, `replace`, `reset`. If parent container is tabbar (tabs=true), jump will be automatically set. +| clone | `bool` | | Scenes marked with `clone` will be treated as templates and cloned into the current scene's parent when pushed. See example. | + +### Animation +| Property | Type | Default | Description | +|-----------|--------|---------|--------------------------------------------| +| duration | `number` | | optional. acts as a shortcut to writing an `applyAnimation` function with `Animated.timing` for a given duration (in ms). | +| direction | `string` | 'horizontal' | direction of animation horizontal/vertical | +| applyAnimation | `function` | | optional if provided overrides the default spring animation | + +### Scene styles +| Property | Type | Default | Description | +|-----------|--------|---------|--------------------------------------------| +| sceneStyle | [`View style`](https://facebook.github.io/react-native/docs/view.html#style) | { flex: 1 } | optional style override for the Scene's component | +| getSceneStyle | `function` | optional | Optionally override the styles for NavigationCard's Animated.View rendering the scene. | + +### Tabs +| Property | Type | Default | Description | +|-----------|--------|---------|--------------------------------------------| +| tabs| `bool` | false | Defines 'TabBar' scene container, so child scenes will be displayed as 'tabs'. If no `component` is defined, built-in `TabBar` is used as renderer. All child scenes are wrapped into own navbar. +| tabBarStyle | [`View style`](https://facebook.github.io/react-native/docs/view.html#style) | | optional style override for the Tabs component | +| hideTabBar | `bool` | false | hides tab bar for this scene (if built-in TabBar component is used as parent renderer)| + +### Navigation Bar +| Property | Type | Default | Description | +|-----------|--------|---------|--------------------------------------------| +| hideNavBar | `bool` | false | hides the navigation bar for this scene | +| navigationBarStyle | [`View style`](https://facebook.github.io/react-native/docs/view.html#style) | | optional style override for the navigation bar | +| navBar | `React.Component` | | optional custom NavBar for the scene. Check built-in NavBar of the component for reference | +| drawerImage | [`Image source`](https://facebook.github.io/react-native/docs/image.html#source) | `'./menu_burger.png'` | Simple way to override the drawerImage in the navBar | + +#### Navigation Bar: Title +| Property | Type | Default | Description | +|-----------|--------|---------|--------------------------------------------| +| title | `string` | null | The title to be displayed in the navigation bar | +| getTitle | `function` | optional | Optionally closure to return a value of the title based on state | +| renderTitle | `function` | optional | Optionally closure to render the title | +| titleStyle | [`Text style`](https://facebook.github.io/react-native/docs/text.html#style) | | optional style override for the title element | + +#### Navigation Bar: Back button +| Property | Type | Default | Description | +|-----------|--------|---------|--------------------------------------------| +| backTitle | `string` | | optional string to display with back button | +| renderBackButton | `function` | | optional closure to render back text or button if this route happens to be the previous route | +| backButtonImage | [`Image source`](https://facebook.github.io/react-native/docs/image.html#source) | `'./back_chevron.png'` | Simple way to override the back button in the navBar | +| backButtonTextStyle | [`Text style`](https://facebook.github.io/react-native/docs/text.html#style) | | optional style override for the back title element | + +#### Navigation Bar: Left button +| Property | Type | Default | Description | +|-----------|--------|---------|--------------------------------------------| +| leftTitle | `string` | | optional string to display on the left if the previous route does not provide `renderBackButton` prop. `renderBackButton` > `leftTitle` > | +| renderLeftButton | `function` | | optional closure to render the left title / buttons element | +| onLeft | `function` | | function will be called when left navBar button is pressed | +| leftButtonImage | [`Image source`](https://facebook.github.io/react-native/docs/image.html#source) | | Image for left button | +| leftButtonIconStyle | [`View style`](https://facebook.github.io/react-native/docs/view.html#style) | | Image style for left button | +| leftButtonStyle | [`View style`](https://facebook.github.io/react-native/docs/view.html#style) | | optional style override for the container of left title / buttons | +| leftButtonTextStyle | [`Text style`](https://facebook.github.io/react-native/docs/text.html#style) | | optional style override for the left title element | + +#### Navigation Bar: Right button +| Property | Type | Default | Description | +|-----------|--------|---------|--------------------------------------------| +| rightTitle | `string` | | optional string to display on the right. `onRight` must be provided for this to appear. | +| renderRightButton | `function` | | optional closure to render the right title / buttons element | +| onRight | `function` | | function will be called when right navBar button is pressed | +| rightButtonImage | [`Image source`](https://facebook.github.io/react-native/docs/image.html#source) | | Image for right button | +| rightButtonIconStyle | [`View style`](https://facebook.github.io/react-native/docs/view.html#style) | | Image style for right button | +| rightButtonStyle | [`View style`](https://facebook.github.io/react-native/docs/view.html#style) | | optional style override for the container of right title / buttons | +| rightButtonTextStyle | [`Text style`](https://facebook.github.io/react-native/docs/text.html#style) | | optional style override for the right title element | +| **...other props** | | | all properties that will be passed to your component instance | diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md new file mode 100644 index 000000000..026734fab --- /dev/null +++ b/docs/CHANGELOG.md @@ -0,0 +1,8 @@ +# Change log +- 3.22.20 fix more ESLint errors, fix passing leftButtonStyle property for back button +- 3.22.18 fix some ESLint errors and ignore pop for root scene +- 3.22.17 allow jump & push together - now you could call Actions.tab2_2() (`tab2_2` is next scene after `tab2`) even if `tab2` is not active +- 3.22.16 simplified syntax for sub-states +- 3.22.15 introduces support for different states inside the same screen. +- 3.22.10 simplifies customization of own NavBar. From now you could import built-in NavBar from the component and customize it. You could set it globally to all scenes by setting `navBar` property for `Router` component. +For all other scenes you may pass rightButton, leftButton for custom buttons or rightTitle & onRight, leftTitle & onLeft for text buttons. \ No newline at end of file diff --git a/docs/DETAILED_EXAMPLE.md b/docs/DETAILED_EXAMPLE.md new file mode 100644 index 000000000..8056afcf2 --- /dev/null +++ b/docs/DETAILED_EXAMPLE.md @@ -0,0 +1,98 @@ +## Detailed Example +![launch](https://cloud.githubusercontent.com/assets/1321329/11692367/7337cfe2-9e9f-11e5-8515-e8b7a9f230ec.gif) + +```jsx +import React, {AppRegistry, Navigator, StyleSheet, Text, View} from 'react-native' +import Launch from './components/Launch' +import Register from './components/Register' +import Login from './components/Login' +import Login2 from './components/Login2' +import {Scene, Router, TabBar, Modal, Schema, Actions, Reducer} from 'react-native-router-flux' +import Error from './components/Error' +import Home from './components/Home' +import TabView from './components/TabView' + +class TabIcon extends React.Component { + render(){ + return ( + {this.props.title} + ); + } +} + +const reducerCreate = params=>{ + const defaultReducer = Reducer(params); + return (state, action)=>{ + console.log("ACTION:", action); + return defaultReducer(state, action); + } +}; + +export default class Example extends React.Component { + render() { + return + + + + + + + + + + + + + alert("Right button")} rightTitle="Right" /> + + + + alert("Left button!")} leftTitle="Left"/> + + + + + + + + + + ; + } +} + +``` + +components/Launch.js (initial screen) + +```jsx +import React, {View, Text, StyleSheet, TouchableHighlight} from 'react-native' +import Button from 'react-native-button' +import {Actions} from 'react-native-router-flux' + +class Launch extends React.Component { + render(){ + return ( + + Launch page + + + + + + + ); + } +} + +var styles = StyleSheet.create({ + container: { + flex: 1, + justifyContent: 'center', + alignItems: 'center', + backgroundColor: 'transparent', + } +}); + +module.exports = Launch; +``` diff --git a/docs/MIGRATION.md b/docs/MIGRATION.md new file mode 100644 index 000000000..7f8a0aab4 --- /dev/null +++ b/docs/MIGRATION.md @@ -0,0 +1,13 @@ +# Migrating from 2.x + +## Breaking changes comparing with 2.x version: +- React Native 0.22 is required +- `Router` is root container now and should not be nested. For nested scenes you should use `Scene` element +- `Route` became `Scene`, now unique `key` attribute is required for each scene (it was `name` attribute before) +- Define all your scenes on top-level, not within `Router` as before (see Example) +- No `Schema` element is supported for now (for simplicity), maybe later it could be added +- No ActionSheet support +- Custom scene renderers are used instead of 'custom' types (like 'modal'), so 'modal' scenes are pushed as usual, but custom renderer will render them as popup. No `dismiss`, just usual `pop` to close such popups. +- No old navigator.sceneConfig support (instead the component uses React Native NavigationAnimatedView for better transitions) +- No onPush/onPop/etc handlers because they are not needed now. If navigation state is changed, container will be re-rendered with changed navigationState property, see `Modal` as Example. +- No header/footer properties are supported for Scene currently - you may include them into Scene component. \ No newline at end of file diff --git a/docs/MINI_TUTORIAL.md b/docs/MINI_TUTORIAL.md new file mode 100644 index 000000000..3a5714933 --- /dev/null +++ b/docs/MINI_TUTORIAL.md @@ -0,0 +1,125 @@ +# Mini-Tutorial + +![super_simple.gif](super_simple.gif) + +In this super simple example, we will just have three files: + +1. Your root index file: `index.js` +2. The first page that is loaded automatically: `PageOne.js` +3. A second page you can navigate to: `PageTwo.js` + +### index.js +```jsx +import React, { Component } from 'react'; +import { Router, Scene } from 'react-native-router-flux'; + +import PageOne from './PageOne'; +import PageTwo from './PageTwo'; + +export default class App extends Component { + render() { + return ( + + + + + + + ) + } +} +``` + +In `react-native-router-flux`, each route (or page) is called a ``. Conventionally, your Scenes should be wrapped inside a root Scene before being finally wrapped inside a `` component that is returned in the `render()` function. + +At the very minimum, each `` component should have the following props: + +- **key**: A unique string that can be used to refer to the particular scene. +- **component**: The component to be rendered for that `Scene` or page. +- **title**: The string to be displayed in the nav bar at the top of the screen. + +Note that the first scene we wish to load has the prop `initial={true}` to indicate that it's the scene that should be initially rendered. + +## From Page to Page + +### PageOne.js +```jsx +import React, { Component } from 'react'; +import { View, Text } from 'react-native'; +import { Actions } from 'react-native-router-flux'; + +export default class PageOne extends Component { + render() { + return ( + + This is PageOne! + + ) + } +} +``` + +To navigate from one route to another, an `Action` must be called. This takes the form of: + +``` +Actions.SCENE_KEY(PARAMS) +``` + +Where `SCENE_KEY` must match the `key` prop defined in one of the Scenes of the `Router` component in the root file. And `PARAMS` refers to a javascript object that will be passed into the resulting scene as props (more on this later). + +Since the PageTwo component has the key of `pageTwo`, all we need to do is to pass in the function `Actions.pageTwo` into the `` component so that it executes the page transition when the text is pressed. + +## Passing Information + +Now let's try to extend our example so that we can pass data from `PageOne` to `PageTwo`. + +In `PageOne.js`, instead of simply passing in `Actions.pageTwo`, we can replace it with `Actions.pageTwo({text: 'Hello World!'})`. In this case, we need to wrap the Action call inside a function to prevent it from executing when this component is rendered. As a result, the render function inside `PageOne.js` should look like this: + +```jsx +render() { + const goToPageTwo = () => Actions.pageTwo({text: 'Hello World!'}); + return ( + + This is PageOne! + + ) +} +``` + +And in `PageTwo.js`, we can use the data being passed in by adding an additional `` component below the existing one like so: + +```jsx +render() { + return ( + + This is PageTwo! + {this.props.text} + + ) +} +``` + +Now, if we navigate to the PageTwo Scene as before, we should see: + +``` +This is PageTwo! +Hello World! +``` + +## Going Forward (or backwards?) + +That pretty much concludes this mini-tutorial, we've covered most of the basics here. There are a lot of things you can do to customize `react-native-router-flux`, this is only the beginning. + +For example, you may want to programmatically go back to the previous Scene. The included navbar already allows you to do this by pressing on the arrow icon at the upper left corner. But you can also call this function at any point in your app for the same effect: + +```js +Actions.pop() +``` + +And should you ever want to refresh the same Scene with new props, you can use: + +```js +Actions.refresh(PARAMS) +``` + +Don't be afraid to explore the docs, you'll be surprised at how much you're able to customize with `react-native-router-flux`! diff --git a/docs/OTHER_INFO.md b/docs/OTHER_INFO.md new file mode 100644 index 000000000..d9cd74b09 --- /dev/null +++ b/docs/OTHER_INFO.md @@ -0,0 +1,104 @@ +# Other Info + +This is a place for information that needs to be documented, but aren't long enough to warrant their own file yet. + +- Modals +- Tabbar +- Custom navbar +- Switch +- Splitting Scenes +- Drawer (side-menu) +- Sub-Scenes + +## Modals +To display a modal use `Modal` as root renderer, so it will render the first element as `normal` scene and all others as popups (when they are pushed), see Example for more details. + +## Tabbar +Every tab has its own navigation bar. However, if you do not set its parent `` with `hideNavBar={true}`, the tabs' navigation bar will be overrided by their parent. + +## Custom nav bar for individual scene or even different state of scene (new feature): +Your scene `component` class could implement _static_ renderNavigationBar(props) method that could return different navbar depending from component props + +## Switch (new feature) +New feature for 3.x release is custom scene renderer that should be used together with tabs={true} property. It allows to select `tab` scene to show depending from app state. +It could be useful for authentication, restricted scenes, etc. Usually you should wrap `Switch` with redux `connect` to pass application state to it: +Following example chooses scene depending from sessionID using Redux: +```jsx +({profile:state.profile}))(Switch)} tabs={true} + selector={props=>props.profile.sessionID ? "main" : "signUp"}> + + + +``` + +## Split your scenes to smaller parts if needed +Scenes concept is similar to iOS storyboard where you describe all your app screens in one place. However for some large apps, you may want to split it, like iOS app could have several iOS storyboards for different areas of the app. +Luckily, you could easy split Scenes using NodeJS built-in require calls: +```jsx + + {require("./scenesForTabBar")} + {require("./scenesForAnotherPart")} + +``` + +scenesForTabBar.js: +```jsx +import React from 'react-native'; +import {Scene} from 'react-native-router-flux'; + +module.exports = + // scenes here +; +``` + +## Drawer (side menu) integration +Example of Drawer custom renderer based on react-native-drawer. Note that the build-in NavBar component supports toggling of drawer. The Drawer implementation just needs to have a function: toggle(); + +```jsx +import React from 'react-native'; +import Drawer from 'react-native-drawer'; +import SideMenu from './SideMenu'; +import {DefaultRenderer} from 'react-native-router-flux'; + +export default class extends Component { + render(){ + const children = this.props.navigationState.children; + return ( + } + tapToClose={true} + openDrawerOffset={0.2} + panCloseMask={0.2} + negotiatePan={true} + tweenHandler={(ratio) => ({ + main: { opacity:Math.max(0.54,1-ratio) } + })}> + + + ); + } +} + +/// then wrap your tabs scene with Drawer: + + + .... + + + +``` +## Sub-scenes support +You could create 'sub-scene' actions by putting them as children for needed 'base' scene without `component` prop and call such action anywhere - 'base' Scene will be updated accordingly. +Example for 'My Account' screen with edit possibility (`MyAccount` component should call `Actions.editAccount()` to enable edit mode and process `save`, `editMode` properties accordingly - display edit controls, save data, etc.): + +```jsx + + + Actions.saveAccount()} leftTitle="Cancel" onLeft={()=>Actions.viewAccount()} /> + + +``` +Note, that almost empty `viewAccount` sub-state here is needed to reset MyAccount to initial params defined for this scene (remove `save`, `editMode` and other properties from original state) +Sure it could be done using Redux, however it will require more coding and programmatic setting NavBar buttons using `refresh`. diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 000000000..32e663268 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,112 @@ +# React Native Router [![react-native-router-flux](http://img.shields.io/npm/dm/react-native-router-flux.svg)](https://www.npmjs.org/package/react-native-router-flux) [![Join the chat at https://gitter.im/aksonov/react-native-router-flux](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/aksonov/react-native-router-flux?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Codacy Badge](https://api.codacy.com/project/badge/grade/c6d869e2367a4fb491efc9de228c5ac6)](https://www.codacy.com/app/aksonov-github/react-native-router-flux) [![npm version](https://badge.fury.io/js/react-native-router-flux.svg)](http://badge.fury.io/js/react-native-router-flux) + +Router for React Native based on new React Native Navigation API. + +## Documentation + +- [Mini-Tutorial](MINI_TUTORIAL.md) +- [API and Configuration](API_CONFIGURATION.md) + - Available Imports + - Router API + - Scene API +- [Detailed Example](DETAILED_EXAMPLE.md) +- [Redux/Flux](REDUX_FLUX.md) +- [Other Info](OTHER_INFO.md) + - Modals + - Tabbar + - Custom navbar + - Switch + - Splitting Scenes + - Drawer (side-menu) + - Sub-Scenes +- [Changelog](CHANGELOG.md) +- [Migrating from 2.x](MIGRATION.md) + +## Features + +`react-native-router-flux` is a routing package that allows you to: + +- Define scene transitions in one central location +- Without having to pass navigator objects around, and allow you to +- Call transitions anywhere in your code with a simple syntax (e.g. `Actions.login()`). + +### New Features and Highlights + +- **Highly Customizable Navigation Bar** - Show/hide the navbar depending on Scene or even the state of a Scene (e.g. Edit/Save navbar for edit mode). + +- **Tab Bar Support** using [react-native-tabs](https://github.com/aksonov/react-native-tabs) (see demo). + +- **Nested Navigators** (e.g. Each tab can have its own navigator, nested in a root navigator). + +- **Custom Scene Renderers** for action sheet, native TabBarIOS or anything else. See built-in `Modal` renderer (to display popups) for example. *Call for PRs!* let's build some custom renderers for ActionSheet, Drawer, etc. Let's make an awesome library! + +- **Dynamic Routing** allows you to choose which scene to render depending on application state (see the `Switch` renderer, useful for authentication). + +- **Bring Your Own Reducer** for navigation state. + +- **Reset History Stack** - The new `reset` Action for clearing the history stack and eliminates the navbar back button. + +- **More Powerful State Control** - Support for having different states while on the same screen. For example, "View My Account" could allow in-place editing of fields and "Save", "Cancel" navigation bar buttons should appear. + +## Getting Started + +Check out the [mini-tutorial](MINI_TUTORIAL.md) for a quick walkthrough of the routing system. + +## Installation +``` +npm i react-native-router-flux --save +``` + +## Usage +In your top-level `index.js`, define your scenes using the `Scene` component and pass it into the `Router` as children: +```jsx +import {Scene, Router} from 'react-native-router-flux'; + +class App extends React.Component { + render() { + return + + + + + + + } +} +``` +Alternatively, you could define all of your scenes during compile time and use it later within `Router`: +```jsx +import {Actions, Scene, Router} from 'react-native-router-flux'; + +const scenes = Actions.create( + + + + + +); + +/* ... */ + +class App extends React.Component { + render() { + return + } +} +``` + +On any Scene, you can also call the following functions by first importing the `Actions` object: +```jsx +import {Actions} from 'react-native-router-flux' +``` +And then: + +* `Actions.ACTION_NAME(PARAMS)` will call the appropriate action and params will be passed to the scene. +* `Actions.pop()` will pop the current screen. +* `Actions.refresh(PARAMS)` will update the properties of the current screen. + +## Production Apps using react-native-router-flux ++ GuavaPass.com ([iOS](https://itunes.apple.com/en/app/guavapass-one-pass-fitness/id1050491044?l=en&mt=8), Android) - offers convenient access to top classes at boutique fitness studios across Asia. + +## Support +Thanks to all who submitted PRs to 2.x release. If you like the component and want to support it, feel free to donate any amount or help with issues. diff --git a/docs/REDUX_FLUX.md b/docs/REDUX_FLUX.md new file mode 100644 index 000000000..b33ea9fb2 --- /dev/null +++ b/docs/REDUX_FLUX.md @@ -0,0 +1,117 @@ +# Redux/Flux +This component doesn't depend on any redux/flux library. It uses new React Native Navigation API and provide own reducer for its navigation state. +You may provide your own reducer if needed. To avoid the creation of initial state, you may pass a reducer creator. +Also all actions will pass themselves to Redux dispatch method if it is passed (i.e. if Router is `connect`ed with Redux) + +The following example will dispatch the `focus` action when a new scene comes into focus. The current scene will be available to components via the `props.scene` property. + +### Step 1 + +First create a reducer for the routing actions that will be dispatched by RNRF. + +```javascript +// reducers/routes.js + +const initialState = { + scene: {}, +}; + +export default function reducer(state = initialState, action = {}) { + switch (action.type) { + // focus action is dispatched when a new screen comes into focus + case "focus": + return { + ...state, + scene: action.scene, + }; + + // ...other actions + + default: + return state; + } +} +``` + +### Step 2 + +Combine this reducer with the rest of the reducers from your app. + +```javascript +// reducers/index.js + +import { combineReducers } from 'redux'; +import routes from './routes'; +// ... other reducers + +export default combineReducers({ + routes, + // ... other reducers +}); + +``` + +### Step 3 + +Create your store, wrap your routes with the redux `Provider` component and connect your Router + + +```jsx +// app.js + +import { Router } from 'react-native-router-flux'; +import { Provider } from 'react-redux'; +import { createStore, applyMiddleware, compose } from 'redux'; +import { connect } from 'react-redux'; + +const RouterWithRedux = connect()(Router); +import reducers from './reducers'; +// other imports... + +// create store... +const middleware = [/* ...your middleware (i.e. thunk) */]; +const store = compose( + applyMiddleware(...middleware) +)(createStore)(reducers); + + +class App extends React.Component { + render () { + return ( + + + // your scenes here + + + ); + } +} + +export default App; +``` + +### Step 4 + +Now you can access the current scene from any connected component. + +```jsx +// components/MyComponent.js +import React, { PropTypes, Text } from 'react-native'; +import { connect } from 'react-redux'; + +class MyComponent extends React.Component { + static propTypes = { + routes: PropTypes.object, + }; + + render () { + return ( + + The current scene is titled {this.props.routes.scene.title}. + + ); + } +} + +export default connect(({routes}) => ({routes}))(MyComponent); +``` \ No newline at end of file diff --git a/docs/super_simple.gif b/docs/super_simple.gif new file mode 100644 index 000000000..8f4718293 Binary files /dev/null and b/docs/super_simple.gif differ