dkershaw
dkershaw

Reputation: 201

React Router (v4) not redirecting in componentDidUpdate()

I'm trying to trigger a redirect if a user is logged in. A successful login triggers an update of this.state.user so I'd like to handle the redirect in componentDidUpdate() or another lifecycle method.

The if statement is getting called when I intend for it to, but the redirect does nothing. Any idea as to how I can fix this? I just want this to update the url so it doesn't necessarily need to use Redirect.

I'm not using user authentication currently and don't intend to add it yet.

import React, { Component } from "react";
import "./App.css";

import { BrowserRouter as Router, Route, Redirect } from "react-router-dom";
import AuthContainer from "./components/AuthContainer";
import ChatSelector from "./components/ChatSelector";
import { debug } from "util";
// import ChatRoomContainer from './components/ChatRoomContainer';

class App extends Component {
  constructor(props) {
    super(props);

    this.state = {
      user: {}
    };
  }

  setUser = user => {
    console.log("setting user");
    this.setState({ user });
  };

  componentDidUpdate() {
    // if a user is logged in, redirect them to chat-selector
    if (Object.keys(this.state.user).length > 0) {
      console.log(this.state.user);
      <Router>
        <Redirect to="/chat-selector" />;
      </Router>;
    }
  }

  render() {
    return (
      <Router>
        <div>
          <Route
            exact
            path="/"
            render={props => (
              <AuthContainer {...props} setUser={this.setUser} />
            )}
          />
          <Route
            exact
            path="/chat-selector"
            render={props => <ChatSelector {...props} user={this.state.user} />}
          />
          {/* <Route exact path='/chatroom' component={ChatRoomContainer}/> */}
        </div>
      </Router>
    );
  }
}

export default App;

Upvotes: 0

Views: 3259

Answers (2)

James
James

Reputation: 3815

There is actually a better way of doing this, and I have recently stumbled across a similar situation.

Since the <Redirect /> technique does not work well with helper functions or lifecycle methods, I suggest to instead use this.props.history.push() inside the ComponentDidUpdate() to perform a redirect. Just remember to wrap your component with the withRouter() HOC.

Example code here: http://blog.jamesattard.com/2018/03/fire-action-creator-after-react-state.html

Upvotes: 0

dkershaw
dkershaw

Reputation: 201

I solved this by placing the if statement within render, and adding a redirect boolean to state.

import React, { Component } from "react";
import "./App.css";

import {
  BrowserRouter as Router,
  Route,
  Redirect,
  withRouter
} from "react-router-dom";
import AuthContainer from "./components/AuthContainer";
import ChatSelector from "./components/ChatSelector";
import { debug } from "util";
// import ChatRoomContainer from './components/ChatRoomContainer';

class App extends Component {
  constructor(props) {
    super(props);

    this.state = {
      user: {},
      redirect: false
    };
  }

  setUser = user => {
    console.log("setting user");
    this.setState({ user });
  };

  redirect = () => {
    this.setState({ redirect: true });
  };

  render() {
    if (
      Object.keys(this.state.user).length > 0 &&
      this.state.redirect === true
    ) {
      this.setState({ redirect: false });
      console.log("logged in");
      return (
        <Router>
          <Redirect to="/chat-selector" />
        </Router>
      );
    } else {
      console.log("not logged in");
    }
    return (
      <Router>
        <div>
          <Route
            exact
            path="/"
            render={props => (
              <AuthContainer
                {...props}
                setUser={this.setUser}
                redirect={this.redirect}
              />
            )}
          />
          <Route
            exact
            path="/chat-selector"
            render={props => <ChatSelector {...props} user={this.state.user} />}
          />
          {/* <Route exact path='/chatroom' component={ChatRoomContainer}/> */}
        </div>
      </Router>
    );
  }
}

export default App;

Upvotes: 2

Related Questions