Using native-router-stream reaction abbreviated, how to update state in view component?

Problem:

I tried using redux in conjunction with the routing provided by react-native-router-flux .

In simple words, it does not work:

  • Redux state changes will not be displayed, but can be successfully logged in the console
  • every time the action is performed, the entire tree of components with scenes will be recreated, which leads to many warnings in the console that the scene with the key "xyz" has already been created.

What I've done:

I used the official sample application response-native-router-flux and added a simple counter example based on redux:

  • simple state: "counter" (can be an integer)
  • gears and actions (increment, decrease)

Below I will show the code, but also find my application on github, do not hesitate to check it: https://github.com/itinance/react-native-router-flux . The Example Reference is an initial example application. And "ExampleRedux" is a copy of an example with a reduction stack and examples of reducers (counter), which I am talking about here.

The main component of the application with the provider and storage:

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 gearboxes:

 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 internal application container for connectix "connect":

I pass state and actions to the scene component:

 <Scene key="launch" component={Launch} title="Launch" initial={true} state={state} {...actions} /> 

All code for 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 light LaunchScreen, which has a simple counter function (and sample routes to demonstrate 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> ); } } 

Actions will be sent when you click the "Increment" button. In the console, a new state can be successfully registered. With each click, it increases one by one. But not that.

When I lower the router and the scenes and activate the launch screen as only one component, everything works fine.

Question:

How to make this redux application work so that views correctly update their state?

For completeness, all code can be found on github .

+6
source share
1 answer

You may have forgotten to connect the Launch component to the repository. What you want to do is similar to what you did in ExampleContainer , i.e.

 export default connect(state => ({ state: state.counter }), (dispatch) => ({ actions: bindActionCreators(actions, dispatch) }) )(Launch); 

and then the correct values ​​will be displayed in your log

+6
source

All Articles