jsdario jsdario - 2 months ago 26
React JSX Question

How to properly use redux with react-native

I have been trying to do a setup using react-native-router-flux and followed the steps. Then tried to follow the examples and also logging a lot of info to try to reverse engineer it to work.
However even following all the information I could find I ended up with some weird state structure:

enter image description here

is a object containing the router state. However initial state is replicated inside
(so it contains again

If I change the ordinary state devices or routes it throws an error as:
Key <name of the key> has already been defined
(other people reporting the same problems here).

So my question is: How do you route your react native apps with redux? Do you use other libraries? Are there any examples or documented resources I could use to fix my code?

Think that it has a typical redux structure. For the sake of the example, this is how it looks on my

import React, { Component } from 'react'
import { Router, Scene } from 'react-native-router-flux'
import { createStore, applyMiddleware, compose } from 'redux'
import { Provider, connect } from 'react-redux'
import logger from 'redux-logger'

import reducers from './reducers'
import Home from './components/home'
import Device from './components/devices'
import Login from './components/login'

const middleware = [logger()]
const store = compose(

const RouterWithRedux = connect(reducers)(Router)

export default class AppContainer extends Component {
render () {
return (
<Provider store={store}>
<Scene key='login' component={Login} title='Login' />
<Scene key='root' initial={true}>
<Scene key='home' component={Home} title='Home' />
<Scene key='device' component={Device} title='Device' />


by my suffering experiences, there is no way to prevent Router re-render if you wrap it under a Provider and listen updates from redux, it is a nature by design.

the point how to prevent this, is: Router should render once and just once it means:

If you didn't connect to redux at all, it works fine since your Router would not be triggered by any of updates from redux.

Also, you can connect() Router to redux to get a dispatch() method props but you can NOT listen to another props.

Thus, the architecture would be:

import {
} from 'react-native-router-flux';

// --- child component can connect and listen to props they want.
const myConnectedMainConponent = connect()(myMainConponent);
const myConnectedLoginConponent = connect()(myLoginConponent);

// --- Create it via Actions.create(), or it will be re-created for each render of your Router
const scenes = Actions.create(
    <Scene key="root">
        <Scene key="login" component={myLoginConponent} />
        <Scene key="main" component={myMainConponent} />

// --- Create connected Router if you want dispatch() method.
// --- Or you can just use vanilla Router
const myConnectedRouter = connect()(Router);

// --- your exported main router
export default class MyExportedRouter extends React.Component {
    constructor(props) {

    render() {
        return (
            <Provider store={store}>
                <myConnectedRouter scenes={scenes} />

p.s. I typed above codes directly here, be aware the syntax error :)

Point Taken:

  1. Router should render once and just once ( connect to get dispatch method only or not connect at all )
  2. pre create scenes via Actions.create() and pass it into Router
  3. move your app main logic into one of the children of Router


this is originally replied on https://github.com/aksonov/react-native-router-flux/issues/376#issuecomment-241965769

thanks @jsdario for mention here, hope this helps