5

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

scene is a object containing the router state. However initial state is replicated inside scene (so it contains again devices and rooms objects).

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 app/index.js:

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(
  applyMiddleware(...middleware)
)(createStore)(reducers)

const RouterWithRedux = connect(reducers)(Router)

export default class AppContainer extends Component {
  render () {
    return (
      <Provider store={store}>
        <RouterWithRedux>
          <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' />
          </Scene>
        </RouterWithRedux>
      </Provider>
    )
  }
}
7
  • It is actually my first sentence. I am trying to guess why my state looks like that Commented Aug 23, 2016 at 20:29
  • Please check out this link; github.com/lynndylanhurley/react-native-router-flux#reduxflux, i followed this guide and i got redux routing i354.photobucket.com/albums/r416/TeNm/… Commented Aug 23, 2016 at 21:05
  • @jsdario I am having a bit of trouble with react-native-router-flux with redux. Do you mind lending me a hand? Would really appreciate it! stackoverflow.com/questions/39609148/… Commented Sep 21, 2016 at 8:35
  • seems you have removed it @JoKo Commented Sep 21, 2016 at 9:22
  • @jsdario Sorry, I was actually able to figure it out myself! Really appreciate you for checking it out though. I encountered one more issue and seems like another member is having the same problem. If you don't mind, could you take a look? stackoverflow.com/questions/39611987/… appreciate it again jsdario! Commented Sep 21, 2016 at 16:16

3 Answers 3

2

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 {
    Router,
    Scene,
    Actions,
} 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} />
    </Scene>
);

// --- 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) {
        super(props);
    };

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

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

Sign up to request clarification or add additional context in comments.

Comments

1

I'm using only redux and react-redux. Creating a store with createStore with some middlewares (after doing combineReducers):

const store = createStore(
  rootReducer,
  compose(applyMiddleware(thunk, promiseMiddleware())),
);

Registering app:

AppRegistry.registerComponent('app', () => () => (
  <Provider store={store}>
    <MainComponent />
  </Provider>
));

Using state in components:

const mapStateToProps = (state) => ({
  isLoading: state.core.isLoading,
});

Connecting component to state using connect:

export default connect(mapStateToProps)(HomeScene);

3 Comments

Could you elaborate a little more on the routing side? Also it looks like you are connecting components to state one by one, rather than using the store. Am I wrong?
Routing? What do you mean here? Yeah, I'm connecting components rather than using store.
By routing I mean, as in the question body, that I am unable to connect redux with react-native-router-flux and so I was asking for alternatives. I'd still want to have a scenes API.
0

You can now also use NavigationExperimental directly from react-native.

You can find more about it on this link.

2 Comments

I am afraid we cannot support experimental features yet, for a production app.
Yeah, I think it's for everyone to decide on their own. My reasoning was it is included in react-native, so it will be developed and probably become a standard (also, it's actually one of react-native-router-flux-like libraries that was merged in). Maybe someone will investigate and think the way I think.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.