0
votes

I cannot redirect to "/" path via react-router. My App.jsx file looks like:

ReactDOM.render(<Router>
    <Switch>
      <Route exact path="/" component={Content} />
      <Route path="/login" component={Auth} />
      {/* <Route component={NotFound} /> */}
    </Switch>
  </Router>, document.getElementById("root"));

ADDED Here is my Auth component which decides what auth form to redirect Login or Register:

export default class Auth extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      isLoginActive: true,
    };

    this.formChange = this.formChange.bind(this);
  }

  formChange() {
    this.setState({ isLoginActive: !this.state.isLoginActive });
  }

  render() {
    const { isLoginActive } = this.state;

    let view = isLoginActive ? (
      <Login apiUrl={apiUrl} formChange={this.formChange} history={this.props.history} />
    ) : (
      <Register apiUrl={apiUrl} formChange={this.formChange} history={this.props.history} />
    );

    return (
      <div className="container">
        {getCookie("token") == null ? view : <Redirect to="/" />}
      </div>
    );
  }
}

And here is Login component that on successful axios request redirects to "/" path that linked to Content component

    export default class Login extends React.Component {
      //constructor
    
      login() {
        // axios request
        this.setState({ userLoggedIn: true });
      }
    
      render() {
        return this.state.userLoggedIn ? (
          <Redirect exact to="/" />
        ) : (
          <div className="base-container">
              <button type="button" className="btn" onClick={this.login}>
                Login
              </button>
            </div>
          </div>
        );
      }
    }

If I change route here <Redirect exact to="/" /> to any other, e.g.'/home' everything works perfectly. So I just can't redirect to '/' route.

2

2 Answers

1
votes

Have you tried add "from" and "to" attributes to <Redirect/> like this:

<Redirect exact from="/login" to="/" />

According to React Router docs you have to use "exact" together with "from" attribute. Notice below.

exact: bool Match from exactly; equivalent to Route.exact.Note: This can only be used in conjunction with from to exactly match a location when rendering a inside of a . See for more details.

I also usually make redirects using the "history" property, that comes as props, provided by react-router-dom, in router components like this one. "It Pushes a new entry onto the history stack". It works like this - this.props.history.push('/')

EDIT ----------

Is your import like "import {BrowserRouter as Router} from 'react-router-dom" ? I have replicate your code here, and works fine. I imported as mentioned above. And in Auth Component I'm passing all router props, not just history, works using <Redirect /> or putting the '/' route on top of the history stack, take a look:

Index.js:

ReactDOM.render(
  <BrowserRouter>
    <Switch>
      <Route exact path="/" component={Content} />
      <Route path="/login" component={Auth} />
    </Switch>
  </BrowserRouter>,
  document.getElementById('root')
)

Auth.js

export default class Auth extends React.Component {
  constructor(props) {
    super(props)

    this.state = {
      isLoginActive: true,
    }
  }

  render() {
    // passing all route props (location, history, match)
    const view = <Login {...this.props} />

    return <div className="container">{view}</div>
  }
}

Login.js

export default class Login extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      userLoggedIn: false,
    }
    this.login = this.login.bind(this)
  }

  login() {
    this.setState({ ...this.state, userLoggedIn: true })
  }

  render() {
    // console.log(this.props)
    return this.state.userLoggedIn ? (
      //   <Redirect exact from="/login" to="/" /> also works
      this.props.history.push('/')
    ) : (
      <div className="base-container">
        <button type="button" className="btn" onClick={this.login}>
          Login
        </button>
      </div>
    )
  }
}

Note also that you have an incorrect extra </div> inside the div with className "base-container" in Login Component

0
votes

The problem was exactly in Auth component as an intermediate layer. After removing it everything worked fine. Felipe Curcio thanks a lot for you help.