I have tried to use redux in combination with the routing provided by react-native-router-flux.
In simple words, it is not working:
I used the official example application of react-native-router-flux and added a simple counter-example based on redux:
Below i will show some code, but also one will find my example application on github, please feel free to check it out: https://github.com/itinance/react-native-router-flux. The "Example" Directory is the original example application. And "ExampleRedux" is a copy of the example with a redux stack and example reducers (a counter), what i am talking about here.
The main application component with provider and store:
import * as reducers from './components/reducers';
const createStoreWithMiddleware = applyMiddleware(thunk)(createStore);
const reducer = combineReducers(reducers);
const store = createStoreWithMiddleware(reducer);
export default class Example extends React.Component {
render() {
return (
<Provider store={store}>
<ExampleContainer/>
</Provider>
);
}
}
My reducers:
const initialState = {
count: 0
};
export default function counter(state = initialState, action = {}) {
switch (action.type) {
case "INCREMENT":
console.log("do increment", state,
{
...state,
count: state.count + 1
}
);
return {
...state,
count: state.count + 1
};
case "DECREMENT":
return {
...state,
count: state.count - 1
};
default:
return state;
}
}
The inner application container for redux' "connect":
I pass the state and actions to the scene component:
<Scene key="launch" component={Launch} title="Launch" initial={true} state={state} {...actions} />
The whole code of this ExampleContainer:
class ExampleContainer extends React.Component {
constructor(props) {
super(props);
}
render() {
const { state, actions } = this.props;
console.log("Props", this.props, state, actions); // everything ok here
return <Router createReducer={reducerCreate}>
<Scene key="modal" component={Modal} >
<Scene key="root" hideNavBar={true}>
<Scene key="echo" clone component={EchoView} />
<Scene key="register" component={Register} title="Register"/>
<Scene key="home" component={Home} title="Replace" type="replace"/>
<Scene key="launch" component={Launch} title="Launch" initial={true} state={state} {...actions} />
.... lots of other scenes ...
</Scene>
</Scene>
<Scene key="error" component={Error}/>
</Scene>
</Router>;
}
}
export default connect(state => ({
state: state.counter
}),
(dispatch) => ({
actions: bindActionCreators(actions, dispatch)
})
)(ExampleContainer);
And this is the dead easy LaunchScreen having simple counter functionality (and example routes for demonstrating the routing):
class Launch extends React.Component {
constructor(props) {
super(props);
console.log(props);
}
render(){
const { state, increment, decrement } = this.props;
console.log("Props 2: ", this.props, state, increment, decrement);
return (
<View {...this.props} style={styles.container}>
<Text>Launch page</Text>
<Text>{state.count}</Text>
<Button onPress={increment}>Increment</Button>
<Button onPress={()=>Actions.login({data:"Custom data", title:"Custom title" })}>Go to Login page</Button>
<Button onPress={Actions.register}>Go to Register page</Button>
<Button onPress={Actions.register2}>Go to Register page without animation</Button>
<Button onPress={()=>Actions.error("Error message")}>Popup error</Button>
<Button onPress={Actions.tabbar}>Go to TabBar page</Button>
<Button onPress={Actions.pop}>back</Button>
</View>
);
}
}
The actions are perfectly dispatched when clicking on Increment-Button. In the console the new state can be logged successfully. It increments one by one with every click. But not in the view.
When i ommit the router and scenes and only activate the launch screen as a single component, everything works fine.
How to make this redux application work, that views will update their state correctly?
For the sake of completeness, the whole code can be found on github.
The primary difference of Flux vs Redux is that Flux includes multiple Stores per app, but Redux includes a single Store per app. Rather than placing state information in multiple Stores across the application, Redux keeps everything in one region of the app.
react-native-router-flux is a different API over react-navigation . It helps users to define all the routes in one central place and navigate and communicate between different screens in an easy way. But it also means that react-native-router-flux inherits all limitations and changes from updated versions.
React Router Native is published to npm. You can install it with either npm or yarn . Once you've initialized a new React Native project, you can copy/paste any of the examples into your index.
You have probably forgotten to connect the Launch
component to the store. What you want to do is similar to what you have done in ExampleContainer
, i.e.
export default connect(state => ({
state: state.counter
}),
(dispatch) => ({
actions: bindActionCreators(actions, dispatch)
})
)(Launch);
and then the correct values will show up in your log
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With