skip to Main Content
import React, { useState, useContext, createContext } from "react";
import { Link, Redirect } from "react-router-dom";
export class Login extends React.Component {
    constructor(props) {
        super(props)
        window.data_login_callback = this.data_login_callback
        this.data_login_callback = this.data_login_callback.bind(this);
    }
    state = { brand: "" }
rend(props){
    console.log("ddd",props)
}
data_login_callback(response) {
    fetch("http://localhost:5000/google_login", {
        method: "POST",
        headers: {
 "Content-Type": "application/json" },
        body: JSON.stringify(response),
    })
    .then((res) => res.json())
    .then((json) => {
        console.log(json);
        if (json.status === "OK") {
            <Link to={json.Redirect}></Link> //want to redirect this but not working
            }
        });      
    }
    render() {  
        return (
           <div className="google-sign-in-btn">
                <div id="g_id_onload"
                    data-client_id="********************"
                    data-context="signin"
                    data-ux_mode="popup"
                    data-callback="data_login_callback"
                    data-auto_prompt="false">
                </div>
                <div class="g_id_signin"
                    data-type="standard"
                    data-shape="rectangular"
                    data-theme="outline"
                    data-text="signin_with"
                 `  data-size="large"
                    data-logo_alignment="left">
                </div>
            </div>
        )
    }
}

i have tried useNavigate ,link,redirect and many things of react but cannot use them in react class component but cannot navigate to a link , json.redirect in data_login_callback contains the link to which i want to get redirected.not able to pass navigate in render since json.redirect is null there and not able to use state in that

3

Answers


  1. In your code you made something that seems not to be the correct action, you returned a react component in case the request was ok and you want to navigate the user to some other screen, okay.

    returning a Link component in that case won’t do anything at all.

    React Router provides a redirect utility that will redirect a user to a certain destination and it should work fine.

    something that worth to mention that React Router’s offical docs recommends use
    redirect over navigate from useNavigate hook in terms of dealing with HTTPs requests or dealing with loaders.
    refer the offical docs for furthermore details https://reactrouter.com/en/main/fetch/redirect

    I hope I helped you and please leave any comment if any of my talk wasn’t clear enough

    Login or Signup to reply.
  2. The Link component must be rendered in order to clicked on to effect any navigation action, simply returning it from an asynchronous callback won’t work. You will need to access either the history object if using react-router-dom@5or below, or thenavigatefunctionif using react-router-dom@6 and up.

    Using the useHistory (RRDv5) or useNavigate (RRDv6) are the easiest ways to do this, but React hooks can only be used in React function components. Normally I wouldn’t cover this conversion but since the Login component code is simple enough I’ll recommend conversion in order to use React hooks.

    If using react-router-dom@5:

    import { useHistory } from "react-router-dom";
    
    const Login = () => {
      const history = useHistory();
    
      const [brand, setBrand] = React.useState("");
    
      React.useEffect(() => {
        data_login_callback(response) {
          fetch("http://localhost:5000/google_login", {
            method: "POST",
            headers: { "Content-Type": "application/json" },
            body: JSON.stringify(response),
          })
            .then((res) => res.json())
            .then((json) => {
              console.log(json);
              if (json.status === "OK") {
                history.push(json.Redirect);
              }
            });      
        }
    
        window.data_login_callback = data_login_callback;
    
        return () => {
          window.data_login_callback = undefined;
        };
      }, []);
    
      return (
        <div className="google-sign-in-btn">
          <div
            id="g_id_onload"
            data-client_id="********************"
            data-context="signin"
            data-ux_mode="popup"
            data-callback="data_login_callback"
            data-auto_prompt="false"
          >
          </div>
          <div
            class="g_id_signin"
            data-type="standard"
            data-shape="rectangular"
            data-theme="outline"
            data-text="signin_with"
            data-size="large"
            data-logo_alignment="left"
          >
          </div>
        </div>
      );
    };
    

    If using react-router-dom@6:

    import { useNavigtate } from "react-router-dom";
    
    const Login = () => {
      const navigate = useNavigate();
    
      const [brand, setBrand] = React.useState("");
    
      React.useEffect(() => {
        data_login_callback(response) {
          fetch("http://localhost:5000/google_login", {
            method: "POST",
            headers: { "Content-Type": "application/json" },
            body: JSON.stringify(response),
          })
            .then((res) => res.json())
            .then((json) => {
              console.log(json);
              if (json.status === "OK") {
                navigate(json.Redirect);
              }
            });      
        }
    
        window.data_login_callback = data_login_callback;
    
        return () => {
          window.data_login_callback = undefined;
        };
      }, []);
    
      return (
        <div className="google-sign-in-btn">
          <div
            id="g_id_onload"
            data-client_id="********************"
            data-context="signin"
            data-ux_mode="popup"
            data-callback="data_login_callback"
            data-auto_prompt="false"
          >
          </div>
          <div
            class="g_id_signin"
            data-type="standard"
            data-shape="rectangular"
            data-theme="outline"
            data-text="signin_with"
            data-size="large"
            data-logo_alignment="left"
          >
          </div>
        </div>
      );
    };
    

    If conversion isn’t your thing and you prefer to stick to outdated React class components, then you can inject either history or navigate as a prop.

    If using RRDv5, import the withRouter Higher Order Component and access this.props.history.

    import { withRouter } from 'react-router-dom';
    
    class Login extends React.Component {
      constructor(props) {
        super(props)
        window.data_login_callback = this.data_login_callback
        this.data_login_callback = this.data_login_callback.bind(this);
      }
    
      state = { brand: "" }
    
      data_login_callback(response) {
        fetch("http://localhost:5000/google_login", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify(response),
        })
          .then((res) => res.json())
          .then((json) => {
            console.log(json);
            if (json.status === "OK") {
              this.props.history.push(json.Redirect);
            }
          });      
      }
    
      render() {  
        return (
          <div className="google-sign-in-btn">
            <div
              id="g_id_onload"
              data-client_id="********************"
              data-context="signin"
              data-ux_mode="popup"
              data-callback="data_login_callback"
              data-auto_prompt="false"
            >
            </div>
            <div
              class="g_id_signin"
              data-type="standard"
              data-shape="rectangular"
              data-theme="outline"
              data-text="signin_with"
              data-size="large"
              data-logo_alignment="left"
            >
            </div>
          </div>
        );
      }
    }
    
    export default withRouter(Login);
    

    If using RRDv6, you’ll have to roll your own withRouter HOC since it was removed.

    import {
      useLocation,
      useNavigate,
      useParams,
    } from "react-router-dom";
    
    export const withRouter = (Component) => (props) => {
      const location = useLocation();
      const navigate = useNavigate();
      const params = useParams();
    
      return (
        <Component
          {...props}
          router={{ location, navigate, params }}
        />
      );
    };
    
    import { withRouter } from '../path/to/withRouter';
    
    class Login extends React.Component {
      constructor(props) {
        super(props)
        window.data_login_callback = this.data_login_callback
        this.data_login_callback = this.data_login_callback.bind(this);
      }
    
      state = { brand: "" }
    
      data_login_callback(response) {
        fetch("http://localhost:5000/google_login", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify(response),
        })
          .then((res) => res.json())
          .then((json) => {
            console.log(json);
            if (json.status === "OK") {
              this.props.router.navigate(json.Redirect);
            }
          });      
      }
    
      render() {  
        return (
          <div className="google-sign-in-btn">
            <div
              id="g_id_onload"
              data-client_id="********************"
              data-context="signin"
              data-ux_mode="popup"
              data-callback="data_login_callback"
              data-auto_prompt="false"
            >
            </div>
            <div
              class="g_id_signin"
              data-type="standard"
              data-shape="rectangular"
              data-theme="outline"
              data-text="signin_with"
              data-size="large"
              data-logo_alignment="left"
            >
            </div>
          </div>
        );
      }
    }
    
    export default withRouter(Login);
    
    Login or Signup to reply.
  3. I like @Drew Reese’s answer more but the quickest way is to fix this without switching off from a class component is to change this:

    <Link to={json.Redirect}></Link>
    

    to

    <Redirect to={json.Redirect}/>
    

    You already imported it, but just didn’t use it.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search