Closed ms88privat closed 9 years ago
I'm not familiar with React-Native Navigator, but from your description, it sounds similar in role to react-router. You can check out https://github.com/acdlite/redux-react-router to see how @acdlite solved the problem of keeping the two sides in sync.
Thank you for this hint. I have to investigate it later on. I keep this issue updated.
You may wanna check out fluxible-router. It won't work with React Native, but it'll show you another example of how to keep both sides in sync.
Hello there @ms88privat - basically I need what is described here. I'm happy to help you build a wrapper for Navigator that works with redux...
@aphillipo thank you for remembering me on this topic! I kept it our of my scope, because for me it isn't that much important for now. I'm on vacation next week and after that if have to finish two projects really fast, so i don't think i have time for it until November. See you then.
Ah I got it all working yesterday. Easier than I thought!
Only problem is it's integrated into my application - should probably be pulled out into a separate module.
It's really nice being able to register routes to a singleton and the change to them by name (and redux action) rather than component. Not everything that Navigator is supported (not even back yet), but it does some clever stuff like check if routes are already mounted and calls popToRoute on the navigator instead of failing!
Will take a look at getting it into a library that you can use later this week.
I'll close as there doesn't appear anything actionable for Redux here, but feel free to continue the discussion!
@aphillipo Any update on this ? A redux/navigator library would be really nice :smile:
It's built, no tests but it works quite well. It feels weird coming from the web thinking about scenes as opposed to web pages/urls...
I'll put a link here when I get round to creating a repo later this week.
@aphillipo Would be great if you could share the solution. TIA
When I approached this, I did a standard action dispatch to change the state of currentScene
in my store. Then I just switch to that new screen on componentWillReceiveProps
in a router object (which acts as middleware). This doesn't really cover popToRoute
, etc, but it's a simple way to hold the state in stores instead of the native component. E.g.
MyRouter.js
componentWillReceiveProps(nextProps) {
if (nextProps.currentScreen && nextProps.currentScreen !== this.props.currentScreen) {
this.refs.navigator.replace({component: nextProps.currentScreen})
}
}
render() {
return (
<Navigator
ref="navigator"
initialRoute={{component: this.props.currentScreen}}
renderScene={this.renderScene} />
)
}
Okay I'm not going to get time to do this... but I'll just paste the code into a Gist for now...
https://gist.github.com/aphillipo/0583601b0deab1e89dcf
Hope this helps even if it isn't a working example, it's pretty close.
Comment here if you want to know anything or want to get it into a repo.
Nice! First glance, you seem to be preloading all the registered routes, which seems memory inefficient. This might help: http://blog.mgechev.com/2015/09/30/lazy-loading-components-routes-services-router-angular-2/
I see what you mean but really this is only for react native and routes aren't mounted to the navigator until they are used. It's not anywhere near perfect what I've done.
I really should take the hour or two get it into a repo with a proper example.
Another thought: to keep it more in-line with a web version and to keep things organized, you might consider using url style paths as identifiers.
Regarding lazy loading. new AsyncRoute({ path: '/about', loader: () => System.import('./components/about/about').then(m => m.About), as: 'about' })
you could consider the new require.ensure of react-native (although the old fashioned callback there would be inconvenient).
I don't understand why it's important to add Lazy Loading on iOS? Do react native panels really use that much memory? I'm not even sure that separate bundles are possible with the way the React Native bundler works!
Yes - I 100% agree with you about URLs as paths/names/identifiers and I'd like for apps to be able to register schemes myapp://some/path/to/the/pages. But I'd rather launch.
For me, lazy loading is always important. It's more of a gut approach without knowing all the specifics of memory management on react-native or iOS. The idea of preloading all the top level components and maintaining direct references to them in a non garbage collectible way just doesn't feel right.
Also, a title attribute makes sense for your route registry (i8n, etc)
I also created a gist based on a modified version of your code. https://gist.github.com/mschipperheyn/4f5158fe4de48ea6b8d5
Love it - definitely an improvement in a few areas! Feel free to run with it in a git repo, happy to contribute :thumbsup:
@aphillipo / @mschipperheyn Nice one!
You might not have to store a list of routeNames
within Router.js
. Because React Native's Navigator
has already a list of all routes, which you can grab by navigator.getCurrentRoutes()
So you can do something like this (instead of current implementation of Router.navigateTo(name)):
navigateTo(name) {
const navigator = this.refs.navigator;
const route = this.props.registry.getRouteByPath(name);
const routeList = navigator.getCurrentRoutes();
if (routeList.indexOf(route) > -1) {
route.direction = BACK;
navigator.popToRoute(route);
} else {
route.direction = FORWARD;
navigator.push(route);
}
}
Also it seems to be a good idea to add a configureScene
to a route (e.g. via an action) to grab it with configureScene
render() {
return <Navigator
ref="navigator"
initialRoute={routerRegistry.getInitialRoute()}
{...this.props}
configureScene={(route) => route.sceneConfig || Navigator.SceneConfigs.FloatFromRight}
/>
So you can handle all kinds of NavigatorSceneConfigs
, not just Navigator.SceneConfigs.FloatFromRight
or Navigator.SceneConfigs.FloatFromLeft
Anyone want to start a repo for this?
Okay I guess I'll start a repo for this tonight incorporating the changes suggested seeing as it seems popular. I like your ideas @sectore - really nice about not needing to manage the route list ourselves. SceneConfigs are something should definitely be configurable on the route I think but how to handle the route direction?
Will then allow you guys to open issues and do pull requests rather than comment on a redux bug!
I'm also going to change the FORWARD and BACK constants to SCENE_PUSH and SCENE_POP. Any objections?
I wonder if it's always just routes that have a scene config (for PUSH and POP) too, the whole function on navigator should be replaceable with a prop which it is currently not... Maybe that's enough flexibility.
@aphillipo You don't have to manage the direction to go forward and then back. Because navigator.popToRoute(route)
or navigator.popToTop()
should play the last scene into opposite direction (without defining a SceneConfig). Just check official Navigator Examples.
Example:
FORWARD
-----------------------
navigator.push(route) // with Navigator.SceneConfigs.FloatFromRight
ViewA ---> float from right ---> ViewB
BACK
-----------------------
navigator.pop() // without any NavigatorSceneConfigs
ViewB ---> float from left ---> ViewA
Okay that's fantastic. Thanks!
Hey @aphillipo @mschipperheyn! I like the GISTs you've created. I'm still missing 'passprops' so that we could navigate to a specific entity/model. Also the passprops need to be taken into account when selecting the popToRoute()
For example: /posts/1 => /posts/2
Yes, you are right. In the meantime, I have been fiddling a bit with code and made some changes. It's working pretty well for me now. I will fiddle a bit further based on the suggestions here, and update the gist and you can all have a go. Perhaps we should make this in to a project.
Yes I will 100% get to making a project from this. I will commit this to a repo now even if it doesn't work...
@aphillipo I'd love to see what you have going
Hey guys, I created this https://github.com/burgalon/react-native-redux-navigator It's still work in progress and not fully working. The difference from the GISTs you came up with is that the entire route stack is saved in redux so that it can be restored to the exact same state and the back hierarchy will be restored (hopefully this will make stuff like Hot reloading work?) Additionally, the store saves the route passProps. I'm not happy with the sync logic as it doesn't give good control on the transitions and navigation... but I'm not sure what would be the right way to go about it
@burgalon cool - will check out thx.
@lynndylanhurley
Hey guys, i added a working example of react-native-redux-navigator
Relevant to the Navigator discussion: https://github.com/facebook/react-native/commit/a3085464f6ea36fc6b53cd0c711c048ffb1516f9
I have removed my code for react-native-redux-navigator in favor of https://github.com/aksonov/react-native-redux-router
Hello Redux fellows,
I am switching from Angular to React(Native) and Redux (yeah!). So maybe I didn't get the whole picture yet but I don't have any idea how to handle the state of a third party component the redux way.
Example and my actual problem: The React-Native Navigator has some methods on it (e.g. push and pop) to handle the navigation between different scenes. So this Navigator Instance has its own state outside of the redux store.
What I am trying to archive is, that i can use the dev-tool time travel to navigate between the scenes in the end.
Thoughts: Is there a ways to handle the state inside the Navigator with a reducer function? Or should i somehow listen to changes on the state and trigger the appropriate Navigator method each time? (I'm concerned about out of sync situations between the redux store and the Navigator state, which may happen)
Greetings