Solved: Integrating the router with Redux is now possible. Check out this repo for an example: https://github.com/rasmniel/rnrfSample
I'm using the react-native-router-flux library and I want to store the current scene on state.
The problem is that the events in the reducer don't fire when navigating.
The app starts up like this:
...
import {Scene, Router} from 'react-native-router-flux';
const ReduxRouter = connect()(Router);
import reducers from './reducers';
import Home from './components/home';
import Login from './components/login';
...
export default
class App extends React.Component {
componentWillMount() {
this.prepareStore();
}
render() {
return (
<Provider store={this.store}>
<ReduxRouter>
<Scene key="root">
<Scene key="home" component={Home}/>
<Scene key="login" component={Login}/>
...
</Scene>
</ReduxRouter>
</Provider>
);
}
prepareStore() {
const initialState = ...
const enhancer = ... // <- Middleware
this.store = createStore(reducers, initialState, enhancer);
persistStore(this.store) ;
}
}
My reducer looks like this (in routeReducer.js):
import {ActionConst} from 'react-native-router-flux'
const INITIAL_STATE = {scene: {}};
export default (state = INITIAL_STATE, {type, scene}) => {
switch (type) {
console.warn(type); // <-- this line prints every time a reducer is called.
case ActionConst.FOCUS:
console.warn('Focus'); // <-- this line never prints.
return {...state, scene};
default:
return state
}
}
... and is combined like this (in reducers.js):
import { combineReducers } from 'redux';
...
import routeReducer from './route-reducer';
export default combineReducers({
...
route: routeReducer,
});
No errors are raised and everything else works as expected - the router works fine for navigation and basic functionality, but none of the events are fired as expected.
I can't seem to find a solution to this problem anywhere. Am I missing a step? I followed the documentation in the library repo (I used docs/v3 as there seem to be no v4 docs yet), but I don't know if I misunderstood something or this is caused by some of the recent updates being pushed to the library (I'm currently on version 4.0.0-beta.14). Any help is appreciated - Thanks!
Maybe you are using older version. Please check Example project from latest beta.14 - I definitely see FOCUS events:
2017-07-26 13:34:41.387 [info][tid:main][RCTBatchedBridge.m:77] Initializing <RCTBatchedBridge: 0x6180001b0f40> (parent: <RCTBridge: 0x6000000db040>, executor: RCTJSCExecutor)
2017-07-26 13:34:41.433 [warn][tid:com.facebook.react.JavaScript][RCTModuleData.mm:220] RCTBridge required dispatch_sync to load RCTDevSettings. This may lead to deadlocks
2017-07-26 13:34:41.653 [info][tid:main][RCTRootView.m:295] Running application Example ({
initialProps = {
};
rootTag = 1;
})
2017-07-26 13:34:41.657 [info][tid:com.facebook.react.JavaScript] Running application "Example" with appParams: {"rootTag":1,"initialProps":{}}. __DEV__ === true, development-level warning are ON, performance optimizations are OFF
2017-07-26 13:34:41.741 [info][tid:com.facebook.react.JavaScript] Launch RENDER
2017-07-26 13:34:49.138 [info][tid:com.facebook.react.JavaScript] 'ACTION:', { type: 'Navigation/NAVIGATE',
routeName: 'login',
params:
{ tintColor: 'red',
cardStyle: { backgroundColor: 'white', shadowOpacity: 1, shadowRadius: 3 },
leftButtonTextStyle: { color: 'green' },
backButtonTextStyle: { color: 'red' },
initial: true,
hideNavBar: true,
init: true,
data: 'Custom data',
title: 'Custom title',
routeName: 'login' } }
2017-07-26 13:34:49.139 [info][tid:com.facebook.react.JavaScript] 'ACTION:', { type: 'REACT_NATIVE_ROUTER_FLUX_BLUR', routeName: '' }
2017-07-26 13:34:49.141 [info][tid:com.facebook.react.JavaScript] 'ACTION:', { type: 'REACT_NATIVE_ROUTER_FLUX_FOCUS',
routeName: 'loginModal',
params:
{ tintColor: 'red',
cardStyle: { backgroundColor: 'white', shadowOpacity: 1, shadowRadius: 3 },
leftButtonTextStyle: { color: 'green' },
backButtonTextStyle: { color: 'red' },
initial: true,
hideNavBar: true,
init: true,
data: 'Custom data',
title: 'Login',
routeName: 'login',
leftTitle: 'Cancel',
onLeft: [Function] } }
2017-07-26 13:34:49.156 [info][tid:com.facebook.react.JavaScript] Login RENDER
2017-07-26 13:34:49.173 [info][tid:com.facebook.react.JavaScript] 'ACTION:', { type: 'Navigation/SET_PARAMS',
key: 'Init-id-1501068881684-14',
params:
{ title: 'Login!',
rightTitle: 'rightTitle',
onRight: [Function: onRight] } }
2017-07-26 13:34:49.174 [info][tid:com.facebook.react.JavaScript] 'ACTION:', { type: 'REACT_NATIVE_ROUTER_FLUX_BLUR', routeName: 'launch' }
2017-07-26 13:34:49.175 [info][tid:com.facebook.react.JavaScript] 'ACTION:', { type: 'REACT_NATIVE_ROUTER_FLUX_FOCUS',
routeName: 'loginModal',
params:
{ tintColor: 'red',
cardStyle: { backgroundColor: 'white', shadowOpacity: 1, shadowRadius: 3 },
leftButtonTextStyle: { color: [Getter/Setter] },
backButtonTextStyle: { color: 'red' },
initial: true,
hideNavBar: true,
init: true,
data: 'Custom data',
title: 'Login!',
routeName: 'login',
leftTitle: 'Cancel',
onLeft: [Function],
rightTitle: 'rightTitle',
onRight: [Function: onRight] } }
2017-07-26 13:34:49.726 [info][tid:com.facebook.react.JavaScript] Login RENDER
I am certainly not using an older version - I'm currently running 4.0.0-beta.14 as stated above.
I can get it to print out a FOCUS event using this code with the Router's createReducer prop:
const reducerCreate = (params) => {
const defaultReducer = new Reducer();
return (state, action) => {
console.warn('Action', action); // <-- this line prints the desired events!
return defaultReducer(state, action);
};
};
... or by just putting my own reducer directly into a function and returning it to the createReducer prop.
const reducerCreate = (params) => {
return routeReducer;
};
But I don't know where to go from here, since I'm using Redux and it's not apparent to me how I utilize the data when I don't have access to them from my Redux reducers. At this point I'm not using the connect function, which makes me think I'm going incorrectly about integrating with Redux. As you can see in my initial post I keep state persistent which is the point with the router too, but it looks like the scenes are on a different state with this configuration.
@rasmniel Could you post link to sample repo with redux usage? I'm using MobX but will try to help if you provide the example. Probably I have to modify RNRF to work with external state provider.
I am also having issues and am currently not able to persist the router state because of this. Its not showing up in redux at all. It doesn't seem like the connect function connects the state of the router with the store.
@aksonov I have constructed a little react-native project to demonstrate the issue.
You will find that the router behaves exactly as described above.
I hope this is sufficient to assist you in fixing the issue, otherwise let me know.
Thanks for your effort!
@hellsan631 RNRF v4 manages navigation state by itself, like v3 version did. I will think how to work with external state, it could be good enhancement.
@rasmniel Thanks, will take a look
@aksonov how do you persist the router state when your application closes? My Idea for a work-around was to keep track of a state change on the router and during rehydration (loading of an existing state) I could navigate the router to the desired component, but it throws errors about setting state during a router transition.
@hellsan631 It will work after this enhancement will be done.
@rasmniel Your example is very helpful. One difficult thing to implement is creation of initial state - reducer must know it at compile time, but Router is created later, runtime. Any ideas how to avoid it?
I am afraid I don't have the answer, but in regards to initializing state, I found this Redux library, which might contain some code that could serve as an inspiration: redux-async-initial-state
I'm guessing you will be able to create an initial state for the Router, which is then be injected into the Redux store as an enhancer, through the applyMiddelwareor compose functions, but this is where my knowledge about react-native ends, I reckon...
Probably I will restore old v3 syntax Actions.create(<Scene>...</Scene>) to create all actions BEFORE Router usage for this. Does it sound good?
I don't mind that syntax - so if it enables storing navigation state inside Redux without breaking new functionality, I say do it!
@rasmniel Okey, please check https://github.com/aksonov/rnrfSample
Check latest master now.
There you go! This works as expected, and events are now firing properly within Redux.
You can safely push the changes to the next release, imo 👍
Thanks for the solution! :)
The example works well, but when I try to use immutable with redux, it shows cannot update during an existing state transition warning. Here is the screen shot and my fork from rnrfSample.
Tried the solution of #2063 but not work.

I tried the sample project and it works fine, really need RNRF + Redux.
Still not actually use it in my production, but by changing RNRF version from ^4.0.0-beta.21 to github:aksonov/react-native-router-flux#redux first thing I notice is the tabs Scene's child seem not read the icon prop (for styling purpose). So I guess the intended version of RNRF to work together with Redux is not sliced from ^4.0.0-beta.21 or maybe accidental coding that makes icon prop not working.
Actually I was trying to show header above tabs Scene to no avail. It's first time I use tabs in RNRF, not sure if can show header too in RNRF prior to 4. To achieve this, a stackoverflow direct me to use static header Component (placed as sibling to RNRF Router), it's easy, but the problem is, I need a Scene that isn't included in tabs to not show this static header. And that's the reason I need RNRF + Redux, to make the static header Component know which Scene is in focus and not rendered on certain Scene(s).
I think with https://github.com/aksonov/react-native-router-flux/issues/2151 I should stick with ^4.0.0-beta.21.
I can make it works with ^4.0.0-beta.21, however to access current Scene I use routeReducer.routes[routeReducer.index].routeName, so not using Actions.currentScene as in the example as it show previous scene in focus. Not sure why it differ, but I can go on with current method.
@jordenchang55, did you happen to figure out a fix for the warning about not updating during a render?
@zlandau2, Sorry for my poor English. What do you mean figure for a fix?
Ah I mean, did you find a way to stop the warning about updating during a render?
Not yet, I tried implementing shouldComponentUpdate(), but not work as well
@aksonov Thanks, there's only one thing I can not figure it out, selector in Scene is not reacting when state change, in v3 I use the state to control access to views, but now I update the state and selector don't even see the changes, what am I not seeing?
export default Actions.create(
<Scene
key="root"
selector={props => {
console.log('selector', props) // <-- THIS NEVER PRINTS
return props.logged ? 'auth' : 'anon'
}}
tabs
unmountScenes
hideTabBar
>
<Scene key="anon" hideNavBar>
<Scene key="login" component={login} />
</Scene>
<Scene key="auth" hideNavBar>
<Scene key="home" component={home} type='reset' initial />
</Scene>
</Scene>
)
How ca we make this in v4?
It is not supported. Use ‘on’ (or onEnter) and success/failure instead
On 17 Nov 2017, at 05:54, Frang Peguero notifications@github.com wrote:
@aksonov https://github.com/aksonov Thanks, there's only one thing I can not figure it out, selector in Scene is not reacting when state change, in v3 I use the state to control access to views, but now I update the state and selector don't even see the changes, what am I not seeing?
export default Actions.create(
key="root"
selector={props => {
console.log('selector', props) // <-- THIS NEVER PRINTS
return props.logged ? 'auth' : 'anon'
}}
tabs
unmountScenes
hideTabBar
>
)
How ca we make this in v4?—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub https://github.com/aksonov/react-native-router-flux/issues/2115#issuecomment-345145293, or mute the thread https://github.com/notifications/unsubscribe-auth/ABQpcf05NEQdysf_dQf3CeGazmFvyyOxks5s3RF2gaJpZM4Ojyd-.
@aksonov Thanks, it works, but not as expected, why? onEnter receive an object of properties passed to the view:
Object {unmountScenes: true, init: true, tabs: true, hideTabBar: true, hideNavBar: true…}
Not the redux state from connect, so is not the same as the previous selector.
Another thing that I notice is that onEnter don't trigger in "father" when going to a "child", control access for groups of routes its a must to have.
So, for now downgrading to v3... 😞
Thanks btw!
when i update test project (https://github.com/aksonov/rnrfSample) to "react": "16.0.0-beta.5",
"react-native": "0.49.5" (my current version) - the project does not start
Update rnrf too
27 нояб. 2017 г., в 11:07, RadiksMan notifications@github.com написал(а):
when i update test project (https://github.com/aksonov/rnrfSample) to "react": "16.0.0-beta.5",
"react-native": "0.49.5",—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or mute the thread.
Update all, but the error still remains (
http://joxi.ru/EA46PPyuw7z5em
@RadiksMan have you solved it?
@kajm No
@aksonov I did the smallest possible example from your example (https://github.com/aksonov/rnrfSample) and i got this error. What do you think cause this error?
@kajm same here
I'm having a different issue, I followed the example almost exactly and getting this error:
My libraries are:
"redux": "3.6.0",
"react-redux": "5.0.4",
"react": "16.2.0",
"react-native": "0.51.0",
"react-native-router-flux": "^4.0.0-beta.24",
containers/main.js
const ReduxRouter = connect((state) => ({ state: state.route }))(Router);
import reducers from '../reducers';
let _this;
const navigator = Actions.create(
<Stack key="root" hideNavBar={true}>
<Scene key="init" component={Init} hideNavBar={true} duration={0} initial={true} />
<Scene key="onboard" component={Tutorial} hideNavBar={true} duration={0} />
<Scene key="authenticate" hideNavBar={true} component={Authenticate} />
<Scene key="signin" component={SignIn} hideNavBar={true} duration={250} />
</Stack>
)
export default class groovemaps extends Component {
render() {
return (
<Provider store={createStore(reducers, {})}>
<ReduxRouter navigator={navigator} />
</Provider>
);
}
}
reducers/router.js
import {Reducer, ActionConst, Actions} from 'react-native-router-flux'
const defaultReducer = Reducer();
export default (state, action) => {
console.log('Reducing action: ', action.type);
switch (action.type) {
case ActionConst.FOCUS:
console.log('FOCUS event fired with scene parameter: ', action.routeName);
return defaultReducer(state, action);
default:
return defaultReducer(state, action);
}
}
reducers/index.js
import { combineReducers } from 'redux';
import router from './router';
import user from './user';
import settings from './settings';
export default combineReducers({
router,
user,
settings
});
@digitaldavenyc
try "import reducers from '../reducers';" after actions.create
@kajm same here.
The only way I can avoid it, is not giving the state. But when I do it, the navigation state is not in my redux store.
Any solution or idea to solve it?
@gsulloa i actually ended up with react-native-navigation by wix instead. Works good in my opinion.
will github:aksonov/react-native-router-flux#redux be merged back to master?
@aksonov
No, it is not related to this topic. Check forked redux sample https://github.com/aksonov/rnrfSample
@code-freakz import sentence will be auto moved to the top of file, use require instead.
@aksonov yes I have downloaded that sample and ran it ok, but it has to be configuared depending on the special branch instead of latest mater, so I ask if(when) that branch will be merged back.
No, it should work with latest master, please check

@aksonov get this error after replacing the RNRF to either npm latest or git master
@fatfatson I get the same error
Need to adopt latest version then... It worked before
@code-freakz I tried that and I still get the undefined property error on Object.getStateForAction
@aksonov Are you sure the code sample will work with the latest on master?
@aksonov Your sample works until 4.0.0-beta.23.
On version 4.0.0-beta.24 and later it gives the error shown on fatfatson comment.
Yes, then deep linking is the reason... I don't know how deep linking should work for external state yet. PR is welcome.
@digitaldavenyc did you find anything ? iam getting the same error . please help me
@prudhvir3ddy I am sorry but I have had to deprecate our integration with RNRF and Redux. It's creating a fairly serious problem for us and may have to just engineer an undesirable solution.
@digitaldavenyc 3.43.0 is working good with latest RN you can try that
@prudhvir3ddy We have spent a lot of time converting to RN 4.0 Beta, downgrading isn't really an option for us at this point.
if any one knew which version working correctly? i tried beta 23,25,27 and 31 sadly nothing seems working, Please help
Hi, I am using following configuration for my project :
react : 16.6.3
react-native : 0.57.4
react-native-router-flux: 4.0.6
So I am trying to integrate redux with my scenes.
My Scene Component
class Login extends Component {
const mapDispatchToProps = dispatch => {
return {
otpSend: () => dispatch(otpSend())
};
};
const mapStateToProps = state => {
return {
routes: state.routes,
otp: state.login.otp
};
};
export default connect(
mapStateToProps,
mapDispatchToProps
)(Login);
}
My App.js Class ( Starting Class )
import Routes from "./src/screens/routes";
const store = configureStore();
export default class App extends Component {
render() {
return (
<Provider store={store}>
<Routes />
</Provider>
);
}
}
My Routes Class :
class Routes extends React.Component {`
reducerCreate(params) {`
const defaultReducer = Reducer(params);`
return (state, action) => {`
this.props.dispatch(action);`
return defaultReducer(state, action);`
};`
}`
render() {
return (
<Router createReducer={this.reducerCreate.bind(this)}>
<Scene key="root">
<Scene key="landing" component={Landing} title="Landing" initial />
<Scene
key="login"
component={Login}
title="Login"
type="reset"
/>
</Scene>
</Router>
);
}
}
export default connect()(Routes);
So my otpSend dispatch method is triggered as expected.
What doesn't work : My props are not getting updated in my Login Scene Component.
The componentDidUpdate method is not triggered.
I am not sure what I am missing or if it is not supported at all by RNRF. Could someone please help me out here 🙏
Update : I got it to work.. Just upgraded libraries and it started to work :|
Most helpful comment
I'm having a different issue, I followed the example almost exactly and getting this error:
My libraries are:
containers/main.js
reducers/router.js
reducers/index.js