react-native-simple-router-community / react-native-simple-router

A community maintained router component for React Native
MIT License
268 stars 56 forks source link

Any way to change route from a reflux / redux store? #112

Open shakdoesgithub opened 8 years ago

shakdoesgithub commented 8 years ago

I have a component that will trigger sign out action on my redux store, from the store I want to change the route to a Sign In component. Is this possible?

davidLeonardi commented 8 years ago

You can use resetToRoute for this On Fri, 8 Apr 2016 at 04:46, shakdoesgithub notifications@github.com wrote:

I have a component that will trigger sign out action on my redux store, from the store I want to change the route to a Sign In component. Is this possible?

— You are receiving this because you are subscribed to this thread. Reply to this email directly or view it on GitHub https://github.com/react-native-simple-router-community/react-native-simple-router/issues/112

ericraio commented 8 years ago

hey @shakdoesgithub the way I achieve this is that I recreate the router state in redux. On every event emitted from the router, i send an action to the redux store.

For every component I have, I created a Higher Order Component that has a "componentWillReceiveProps" and when the state updates, i look at the router state and perform a "toRoute" call.

This allows me to dispatch router actions from any other action and the route will change.

anhldbk commented 8 years ago

@ericraio That's a good approach.

Additionally, I think we could modify class Router to allow any one call its transition methods. For example, currently we have:

  onForward(nextRoute, navigator) {
    navigator.push(
      Object.assign(nextRoute, { index: this.state.route.index + 1 || 1 })
    );
  }

We may define a certain function like:

toRoute(nextRoute){
....
}

Is that better?

ericraio commented 8 years ago

@anhldbk yeah thats a good idea, that would eliminate the dependency on using the prop and the need I had for using this mixin

anhldbk commented 8 years ago

@ericraio , @shakdoesgithub I've read the code in class Router and found out that: the router already exposes such navigation functions:

   // line #279
    this.toRoute = goForward;
    this.toBack = goBackwards;
    this.replaceRoute = replaceRoute;
    this.resetToRoute = resetToRoute;
    this.reset = goToFirstRoute;

So it's really straightforward to get redux works with this component.

ericraio commented 8 years ago

@anhldbk when I was looking into this, I was running into issues where I couldn't call a method on the router to change the route and components that the router renders were able to access the props.

with my high order component, I was able to dry up the code with the mapStateToProps and create a common componentWillReceiveProps to handle the route transitions, not the cleanest implementation but I haven't had to change the code for months.

anhldbk commented 8 years ago

@ericraio How come? Here is my code:

The app

import React, { StyleSheet, View, Text } from 'react-native';
import Router from 'react-native-simple-router';
import LaunchPage from './pages/LaunchPage';

const firstRoute = {
  name: 'Home World',
  component: LaunchPage,
  statusBarProps: {
    animated: true,
    backgroundColor: 'red',
  },
  data: {
    message: 'Hello World from Vietnam'
  }
};

const styles = StyleSheet.create({
  header: {
    backgroundColor: '#5cafec',
    height: 56
  },
});
const statusBarProps = {
  backgroundColor: '#1b6298',
};

export default class TwitterApp extends React.Component {
  render() {
    return (
        <Router
          firstRoute={firstRoute}
          headerStyle={styles.header}
          statusBarProps={statusBarProps}
          handleBackAndroid
          ref = {(router) => {
            router.toRoute({ // here toRoute works as expected
              name: 'Home World',
              component: LaunchPage,
              statusBarProps: {
                animated: true,
                backgroundColor: 'red',
              },
              data: {
                message: 'Hey Eric, dont you see?'
              }
            });
          }}
        />
    );
  }
}

LaunchPage which is responsible for displaying a message stored in props

// LaunchPage.js
import React, { StyleSheet, View, Text } from 'react-native';

class LaunchPage extends React.Component {
  constructor(props) {
    super(props);
    this.styles = StyleSheet.create({
      container: {
        flex: 1,
        backgroundColor: '#f5f8fa',
      },
    });
  }

  render() {
    return (
      <View style={this.styles.container}>
        <Text>{this.props.data.message}</Text>
      </View>
    );
  }
}

export default LaunchPage;