• This repository has been archived on 18/Jan/2022
  • Stars
    star
    296
  • Rank 135,649 (Top 3 %)
  • Language
    JavaScript
  • License
    Other
  • Created over 6 years ago
  • Updated about 3 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Redux middleware and utils for React Navigation

react-navigation-redux-helpers

This package allows the user to manage their React Navigation state from within Redux.

DEPRECATED as of React Navigation 5

React Navigation no longer supports storing its state within Redux. You should be able to refactor your custom navigation logic into custom navigators, custom routers, and onStateChange callbacks.

How it works

  1. In React Navigation, "containers" wrap navigators, and own the state for that navigator and any nested navigators. This package implements a container that uses Redux as a backing store.
  2. A Redux middleware is used so that any events that mutate the navigation state properly trigger React Navigation's event listeners.
  3. Finally, a reducer enables React Navigation actions to mutate the Redux state.

Motivation

Most projects that are using both Redux and React Navigation don't need this library. Things like state persistence and BackHandler behavior aren't handled directly by createReduxContainer, but are handled by the default createAppContainer. However, there are some things this library makes easier:

  1. It's possible to implement custom actions, allowing you to manipulate the navigation state in ways that aren't possible with the stock React Navigation actions. Though it's possible to implement custom routers in React Navigation to do this, it's arguably cleaner via Redux. (If you want animations to run on your action, make sure to set isTransitioning to true!)
  2. This library allows the user to customize the persistence of their navigation state. For instance, you could choose to persist your navigation state in encrypted storage. Most users don't need this, as there are no practical downsides to handling persistence of navigation state and Redux state separately. Note that stock React Navigation supports some basic degree of persistence customization.
  3. You can implement custom reducer behavior to validate state and maintain consistency between navigation state and other application state. This is again possible with custom routers, but likely cleaner to implement without, especially in the context of an existing Redux setup.

Installation

yarn add react-navigation-redux-helpers

or

npm install --save react-navigation-redux-helpers

Example

import {
  createStackNavigator,
} from 'react-navigation';
import {
  createStore,
  applyMiddleware,
  combineReducers,
} from 'redux';
import {
  createReduxContainer,
  createReactNavigationReduxMiddleware,
  createNavigationReducer,
} from 'react-navigation-redux-helpers';
import { Provider, connect } from 'react-redux';
import React from 'react';

const AppNavigator = createStackNavigator(AppRouteConfigs);

const navReducer = createNavigationReducer(AppNavigator);
const appReducer = combineReducers({
  nav: navReducer,
  ...
});

const middleware = createReactNavigationReduxMiddleware(
  state => state.nav,
);

const App = createReduxContainer(AppNavigator);
const mapStateToProps = (state) => ({
  state: state.nav,
});
const AppWithNavigationState = connect(mapStateToProps)(App);

const store = createStore(
  appReducer,
  applyMiddleware(middleware),
);

class Root extends React.Component {
  render() {
    return (
      <Provider store={store}>
        <AppWithNavigationState />
      </Provider>
    );
  }
}

API

createReactNavigationReduxMiddleware (required)

function createReactNavigationReduxMiddleware<State: {}>(
  navStateSelector: (state: State) => NavigationState,
  key?: string,
): Middleware<State, *, *>;
  • Returns a middleware that can be applied to a Redux store.
  • Param navStateSelector selects the navigation state from your store.
  • Param key needs to be unique for the Redux store and consistent with the call to createReduxContainer below. You can leave it out if you only have one store.

createReduxContainer (required)

function createReduxContainer(
  navigator: Navigator,
  key?: string,
): React.ComponentType<{ state: NavigationState, dispatch: Dispatch }>;
  • Returns a HOC (higher-order component) that wraps your root navigator.
  • Param navigator is your root navigator (React component).
  • Param key needs to be consistent with the call to createReactNavigationReduxMiddleware above. You can leave it out if you only have one store.
  • Returns a component to use in place of your root navigator. Pass it state and dispatch props that you get via react-redux's connect.

createNavigationReducer (optional)

function createNavigationReducer(navigator: Navigator): Reducer<*, *>;
  • Call createNavigationReducer in the global scope to construct a navigation reducer.
  • This basically just wraps navigator.router.getStateForAction, which you can call directly if you'd prefer.
  • Param navigator is your root navigator (React component).
  • Call this reducer from your master reducer, or combine using combineReducers.

Miscellaneous

Mocking tests

To make Jest tests work with your React Navigation app, you need to change the Jest preset in your package.json:

"jest": {
  "preset": "react-native",
  "transformIgnorePatterns": [
    "node_modules/(?!(jest-)?react-native|@?react-navigation|react-navigation-redux-helpers)"
  ]
}

Back button

Here is a code snippet that demonstrates how the user might handle the hardware back button on platforms like Android:

import React from "react";
import { BackHandler } from "react-native";
import { NavigationActions } from "react-navigation";

/* your other setup code here! this is not a runnable snippet */

class ReduxNavigation extends React.Component {
  componentDidMount() {
    BackHandler.addEventListener("hardwareBackPress", this.onBackPress);
  }

  componentWillUnmount() {
    BackHandler.removeEventListener("hardwareBackPress", this.onBackPress);
  }

  onBackPress = () => {
    const { dispatch, nav } = this.props;
    if (nav.index === 0) {
      return false;
    }

    dispatch(NavigationActions.back());
    return true;
  };

  render() {
    /* more setup code here! this is not a runnable snippet */
    return <AppNavigator navigation={navigation} />;
  }
}

More Repositories

1

react-navigation

Routing and navigation for your React Native apps
TypeScript
23,162
star
2

react-native-safe-area-view

⚠️ Deprecated: use the successor react-native-safe-area-context instead!
TypeScript
660
star
3

hooks

React hooks for convenient react-navigation use
TypeScript
576
star
4

navigation-ex

Routing and navigation for your React Native apps
TypeScript
495
star
5

stack

Stack navigator for React Navigation
TypeScript
389
star
6

tabs

Tab navigators for React Navigation
TypeScript
326
star
7

react-navigation.github.io

Home of the documentation and other miscellanea
JavaScript
308
star
8

material-bottom-tabs

A Material Design bottom tab navigator for React Navigation
TypeScript
175
star
9

animated-switch

A switch navigator but with transitions between screens powered by the react-native-reanimated Transitions API
TypeScript
158
star
10

drawer

Drawer navigator for React Navigation
TypeScript
143
star
11

search-layout

A basic search screen layout for usage with React Navigation.
JavaScript
124
star
12

web

Tools for react-navigation on web browsers and servers
JavaScript
94
star
13

rfcs

RFCs for changes to React Navigation
88
star
14

experimental-transitioner

A navigator for custom screen transitions with React Navigation and React Native
JavaScript
73
star
15

deep-linking-example

Example of usage of deep linking for blog post in React Navigation
TypeScript
64
star
16

core

Core utilities for the react-navigation framework shared between the native and web implementations.
JavaScript
62
star
17

native

React Native support for React Navigation. You probably don't need to use this directly, it's included in the react-navigation package.
JavaScript
46
star
18

web-server-example

Example for react-navigation and server-side rendering
JavaScript
44
star
19

create-react-app-example

Example create-react-app using react navigation
JavaScript
38
star
20

reanimated-stacks

TypeScript
21
star
21

boilerplate

Boilerplate app using React Navigation
TypeScript
13
star
22

theme-example

An example project with themes
Objective-C
12
star
23

check-versions-action

Check for missing or outdated versions of packages mentioned in the issue
JavaScript
4
star
24

ci-webhook

JavaScript
3
star
25

bot

A GitHub bot for react-navigation issues (currently unused)
JavaScript
3
star
26

deprecated-tab-navigator

Don't use this unless you have to. You will know if you have to
JavaScript
2
star
27

react-navigation-4

Code of React Navigation 4 for archiving
TypeScript
1
star