remix-run / react-router

Declarative routing for React
https://reactrouter.com
MIT License
52.78k stars 10.22k forks source link

Redirect not working #5419

Closed joshjconlin closed 7 years ago

joshjconlin commented 7 years ago

I'm having an issue where the Redirect component isn't working. when my component mounts, it never redirects from '/' route to the '/auth/login' route that its supposed to. here is the route code, followed by the rest of the file.

    if (!this.props.currentUser) {
      return (
        <Auth>
          <Switch>
            <Route key={`${this.state.il8n}-register`} path="/auth/register" component={() => <Register language={this.state.il8n} />} />
            <Route key={`${this.state.il8n}-reset`} path="/auth/forgot-password" component={ForgotPassword} />
            <Route key={`${this.state.il8n}-login`} path="/auth/login" component={Login} />
            <Redirect to="/auth/login" />
          </Switch>
        </Auth>
      );
    }

    return (
      <Switch>
        <Route key="logout" exact path="/logout" component={Logout} />
        <Route key="settings" path="/settings" component={Settings} />
        <Route key="home" path="/home/:tab" component={LocationDashboard} />
        <Redirect key="home-redirect" to="/home/all" />,
      </Switch>
    );
  }

the entire file

import React, { Component } from 'react';
import 'intl';
import { NativeRouter, Redirect, Route, Switch } from 'react-router-native';
import { addLocaleData, IntlProvider } from 'react-intl';
import esLocaleData from 'react-intl/locale-data/es';
import { connect } from 'react-redux';
import FCM, { FCMEvent } from 'react-native-fcm';
import Mathjs from 'mathjs';
import FlatButton from '../../components/FlatButton';
import Master from '../Master';
import Auth from '../Auth';
import hasSubscription from '../SubscriptionController';
import Text from '../../components/Text';
import hasTheme from '../../styles/hasTheme';

import selectApp from './selectors';
import * as AuthActions from '../Auth/actions';
import * as AppActions from '../App/actions';
import * as AccountActions from '../Account/actions';
import getLocaleData from '../../i18n';
import convert from '../../helpers/conversions';
import { snap } from '../../helpers/rounding';

import Login from '../Auth/Login';
import Logout from '../Auth/Logout';
import Register from '../Auth/Register';
import ForgotPassword from '../Auth/ForgotPassword';
import Settings from '../Settings';
import LocationDashboard from '../LocationDashboard';

addLocaleData(esLocaleData);

class App extends Component {

  static propTypes = {
    currentUser: PropTypes.object,
    refreshAuth: PropTypes.func.isRequired,
    pushSnackBarMessage: PropTypes.func.isRequired,
    pushPrompt: PropTypes.func.isRequired,
    authLoaded: PropTypes.bool,
    fetchAlarmDefinitions: PropTypes.func,
    storeLocation: PropTypes.func,
    updateAccount: PropTypes.func,
    initialLocation: PropTypes.object,
  };

  static defaultProps = {
    authLoaded: false,
    currentUser: undefined,
  };

  static childContextTypes = {
    currentUser: PropTypes.object,
    promptManager: PropTypes.object,
    snackBarManager: PropTypes.object,
    convert: PropTypes.func,
  };

  state = {
    il8n: 'en',
  };

  getChildContext() {
    return {
      currentUser: this.props.currentUser,
      snackBarManager: {
        pushMessage: async (message, actionText, onActionPress) => {
          await this.pushSnackBarMessage(message, actionText, onActionPress);
        },
      },
      promptManager: {
        pushMessage: async (message, buttons = []) => {
          await this.pushPrompt(message, buttons);
        },
        pushSuccess: async (message) => {
          await this.pushPrompt(message, <FlatButton success title="Ok!" />);
        },
        pushError: async (message) => {
          await this.pushPrompt(message, <FlatButton warning title="Ok" />);
        },
      },
      convert: (inputValue, inputUnit, decorate = true, inputStep = null, roundingDecimals = 0) => {
        const { value, suffix } = convert(
          inputValue,
          inputUnit,
          this.props.currentUser.getIn(['settings', 'measurement']) === 'imperial',
        );
        if (isNaN(inputValue)) {
          return inputValue;
        }
        let outputValue = inputStep !== null ? snap(value, inputStep) : value;
        const roundingFactor = 10 ** roundingDecimals;
        outputValue = Math.round(outputValue * roundingFactor) / roundingFactor;
        // return decorate ? `${inputUnit === 'cm' ? this.toFraction(outputValue) : outputValue}${suffix}` : outputValue;
        return decorate ? `${outputValue}${suffix}` : outputValue;
      },
    };
  }

  componentDidMount() {
    this.props.refreshAuth();
  }

  componentWillUpdate(nextProps) {
    if (nextProps.currentUser) {
      FCM.setBadgeNumber(0);
      this.props.updateAccount({ badge_count: 0 });
    }
    if (nextProps.currentUser && !this.props.currentUser) {
      this.addFcmToken();
      this.fetchData().done();
    }
  }

  componentWillUnmount() {
    this.refreshTokenListener.remove();
  }

  getRoutes() {
    if (!this.props.currentUser) {
      return (
        <Auth>
          <Switch>
            <Route key={`${this.state.il8n}-register`} path="/auth/register" component={() => <Register language={this.state.il8n} />} />
            <Route key={`${this.state.il8n}-reset`} path="/auth/forgot-password" component={ForgotPassword} />
            <Route key={`${this.state.il8n}-login`} path="/auth/login" component={Login} />
            <Redirect to="/auth/login" />
          </Switch>
        </Auth>
      );
    }

    return (
      <Switch>
        <Route key="logout" exact path="/logout" component={Logout} />
        <Route key="settings" path="/settings" component={Settings} />
        <Route key="home" path="/home/:tab" component={LocationDashboard} />
        <Redirect key="home-redirect" to="/home/all" />,
      </Switch>
    );
  }

  toFraction = (decimal) => (
    Mathjs.fraction(decimal).toFraction(true)
  );

  addFcmToken = () => {
    FCM.getFCMToken().then((token) => this.handleToken(token));
    this.refreshTokenListener = FCM.on(FCMEvent.RefreshToken, (token) => this.handleToken(token)); // fcm token may not be available on first load, catch it here
  };

  handleToken = (token) => {
    this.props.updateAccount({ fcm_token: token }); // store fcm token in the server
  };

  fetchData = async () => {
    await this.props.fetchAlarmDefinitions();
  };

  pushPrompt = (message, buttons = []) => this.props.pushPrompt(message, buttons);
  pushSnackBarMessage = (message, actionText, onActionPress) => this.props.pushSnackBarMessage(message, actionText, onActionPress);

  changeIl8n = () => {
    if (this.state.il8n === 'en') {
      this.setState({ il8n: 'es' });
    } else {
      this.setState({ il8n: 'en' });
    }
  };

  render() {
    const il8nConfig = getLocaleData(
      this.props.authLoaded && this.props.currentUser ? this.props.currentUser.getIn(['settings', 'language']) : this.state.il8n,
    );

    return (
      <IntlProvider
        locale={il8nConfig.locale}
        textComponent={Text}
        messages={il8nConfig.messages}
      >
        <NativeRouter>
          <Master
            toggleIl8n={this.changeIl8n}
            currentIl8n={this.state.il8n}
            onLocationChange={this.props.storeLocation}
            initialLocation={this.props.initialLocation}
          >
            {this.props.authLoaded && this.getRoutes()}
          </Master>
        </NativeRouter>
      </IntlProvider>
    );
  }
}

const mapStateToProps = selectApp();

function mapDispatchToProps(dispatch) {
  return {
    dispatch,
    refreshAuth: () => dispatch(AuthActions.refresh()),
    storeLocation: (location) => dispatch(AppActions.storeLocation(location)),
    shiftSnackBarMessage: () => dispatch(AppActions.shiftSnackBarMessage()),
    pushSnackBarMessage: (message, actionText, onActionPress) => dispatch(
      AppActions.pushSnackBarMessage(message, actionText, onActionPress)
    ),
    pushPrompt: (message, buttons) => dispatch(
      AppActions.pushPrompt(message, buttons)
    ),
    fetchAlarmDefinitions: () => dispatch(AppActions.fetchAlarmDefinitions()),
    updateAccount: (values) => dispatch(AccountActions.update('', values)),
  };
}

export default hasTheme()(connect(mapStateToProps, mapDispatchToProps)(
  hasSubscription()(App)
));
timdorr commented 7 years ago

This is a bug tracker, not a support system. For usage questions, please use Stack Overflow or Reactiflux. Thanks!

joshjconlin commented 7 years ago

this is a bug report, your redirect code is not working, i'm reporting that

pshrmn commented 7 years ago

You have removed the entire issue template that is provided for reporting bugs and replaced it with a wall of code. What does that accomplish? Are we supposed to read through that and figure out what is wrong? It is all your code, so it would just reveal bugs in your code. As TIm said, we're not here to debug your code for you.

If you think that a bug exists, please provide a reproducible test case (something we can actually run!) and it will be looked into.