expo / ex-navigation

Route-centric navigation for React Native
997 stars 201 forks source link

Missing an example of how to connect ex-navigation to an existing redux store #44

Closed zubko closed 8 years ago

zubko commented 8 years ago

Hi, I have more or less common setup of redux store with couple of reducers, middlewares and redux-persist. Ideally I want to make a branch in this store and give it to be used by ex-navigation, to have 1 store in the app with logging and persistence. But I'm lacking some understanding of ex-navigation and redux.

Small question, is it at all smth that was expected and has support in the library?

Bigger question, can you show an example pls?

qimingfang commented 8 years ago

@zubko I did a bit digging and got this configured to work with my custom redux store. Here are my steps

1) Add in the appropriate reducer into your reducers

import { NavigationReducer as exnavigation } from '@exponent/ex-navigation'
const rootReducer = combineReducers({
  ...
  exnavigation
})

2) update your createStore with createNavigationEnabledStore() If you are planning on using a different redux slice other than navigation, be sure to define it. I.e.

const store = createNavigationEnabledStore(createStore, 'exnavigation')(
  rootReducer,
  initialState,
  enhancers
)

3) use a NavigationContext to create the NavigationProvider

import {
  NavigationContext
} from '@exponent/ex-navigation'

const context = new NavigationContext({ store, router: Router })

render() {
  ...
  <NavigationProvider context={context}>
    <StackNavigation initialRoute={Router.getRoute('init')} />
  </NavigationProvider>
}

Happy to open a PR for this and add this to the README too

zubko commented 8 years ago

Thanks for sharing your code @qimingfang !

I also got a little time to experiment with it recently.

My code is similar to yours only I want to use middlewares and redux-persist so I have:

  const createStoreWithMiddleware = applyMiddleware(...middlewares)(createStore);
  const createStoreWithNavigation = createNavigationEnabledStore({createStore: createStoreWithMiddleware})
  const store = createStoreWithNavigation(rootReducer, {}, autoRehydrate());

So at first launch now it works perfectly, thanks to Exponent guys who've baked in this flexibility, and the logging shows that ex-navigation uses its own branch in the rootReducer as I wanted

The thing i still need to make working is loading the data from previous session with redux-persist. The data is loaded fine and I see in the log that the structure of ex-navigation branch in the store is fine, but on the loading event ex-navigation freaks out and blinks into empty screen instead of picking the navigation structure from the last session as i hoped it will do automatically for me :) ,

so if you interested in additional challenge, can you try pls to add redux-persist to the cocktail on your side? :)

zubko commented 8 years ago

I see that it's better not to religiously follow the redux's "single store per app" mantra in this case. The redux store of ex-navigation is its own implementation detail, and its better not to start parsing it in the app in order to recreate the navigation stack of the last session. Esp that my app has maybe 8 screens total, so it's very easy to have a localized solution which will cover only needed cases.

So, as of now, I've lost the point of mixing the stores. :/ Maybe there are some other use cases for that. At least adding a 'logger' middleware can be useful to get to know the internals of ex-navigation better.

sibelius commented 8 years ago

@zubko is this solved? can u close this or send a PR to improve docs?

jsdario commented 8 years ago

I am also interested in this feature / configuration. How is that you are not interested in persist the router state?

satya164 commented 8 years ago

@jsdario https://github.com/exponentjs/ex-navigation#integrate-with-your-existing-redux-store

jsdario commented 8 years ago

Thanks @satya164, but even though I got it "working" I am finding the same issue as @zubko. Quote:

The thing i still need to make working is loading the data from previous session with redux-persist. The data is loaded fine and I see in the log that the structure of ex-navigation branch in the store is fine, but on the loading event ex-navigation freaks out and blinks into empty screen instead of picking the navigation structure from the last session as i hoped it will do automatically for me :) ,

satya164 commented 8 years ago

@skevy any idea? I'm also interested in persisting the navigation state