brlaxson
brlaxson

Reputation: 31

How do I link routes in React with react-router-dom dynamically using button?

I am very new to using React and JSX and was unsure how to dynamically set a link in my react app. I am trying to make it so that on the login page, if the user successfully inputs their username and password, it redirects to the homepage, and if they do not match it would reload the login page. This login form makes a fetch call to a Flask API, which returns success on a correct matching of the username and password with my database. The button that links the login page to the signup page currently works, but using similar logic does not work with the login button

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import { BrowserRouter } from 'react-router-dom';
import * as serviceWorker from './serviceWorker';
import 'bootstrap/dist/css/bootstrap.css';
import 'semantic-ui-css/semantic.min.css'

ReactDOM.render(
  <React.StrictMode>
    <BrowserRouter>
      <App />
    </BrowserRouter>
  </React.StrictMode>,
  document.getElementById('root')
);

App.js

import React, {useEffect, useState, Component} from 'react';
import './App.css';
import {NewUserInfo} from './components/NewUserInfo';
import {Login} from './components/Login';
import {Register} from './components/Register';
import {Container} from "semantic-ui-react";
import {BrowserRouter, Route, Switch} from 'react-router-dom';
import Homepage from './components/Homepage';
import Tabs from './components/Tabs';
//import Header from './components/Header';
import Journal from './components/Journal';
import Survey from './components/Survey';
import Profile from './components/Profile';


function App(){
    return (
      <div>
        <Switch>
          <Route exact path="/" component={Login}/>
          <Route path="/register" component={Register}/>
          <Route path="/homepage" component={Homepage}/>
          <Route path="/profile" component={Profile}/>
        </Switch>
      </div>

    );
}

export default App;

Login.js

import React, { Component, useState } from "react";
import {Button, Form, FormGroup, Label, Input} from 'reactstrap';
export const Login = () => {
    const [email_or_username, setName] = useState('');
    const [password, setPassword] = useState('');
    const [is_contributor, setContributor] = useState(false);
    var ref = "/";
    return (           
        <div> 
            <Form className="login-form">
                <h1>
                <div className="text-right">
                    <Button
                        href="/register"
                        className=" btn-dark text-right">
                        sign up
                    </Button>
                </div>
                <span className="font-weight-bold">Mindify</span>
                </h1>
                <FormGroup>
                    <Label>Username or Email</Label>
                    <h2></h2>
                    <Input 
                        value={email_or_username} 
                        placeholder = "Username or Email" 
                        onChange={e => setName(e.target.value)}/>
                </FormGroup>

                <FormGroup>
                    <label>Password</label>
                    <h2></h2>
                    <Input 
                        value={password} 
                        placeholder = "Password"
                        onChange={e => setPassword(e.target.value)}/>
                </FormGroup>

                <FormGroup>
                    <div className="text-center">
                    <Input 
                        type="checkbox"
                        value={is_contributor}
                        onChange={e => setContributor(e.target.checked)}/>
                        Contributor
                    </div>                    
                </FormGroup>


                <Button onClick={async () =>{
                     const login = {email_or_username, password, is_contributor};
                     console.log(JSON.stringify(login));
                     const response = await fetch('http://127.0.0.1:5000/api/login', {
                         method: 'POST',
                         headers:{
                            'Content-Type': 'application/json'
                         },
                         body: JSON.stringify(login)
                     })
                     .then(response => {
                         console.log(response.status);
                         if (response.status === 201) {
                            console.log("Successful Login"); 
                            ref="/homepage";
                            console.log(ref);
                            //redirect to home page
                         }
                         else if (response.status === 204) {
                            console.log("Invalid Username or Password or Incorrect Permissions");
                            ref="/";
                            console.log(ref);
                            // reload login page
                         }
                     })
                     .catch(error => console.log(error))

                    }}
                    href={ref}
                    className="btn-lg btn-dark btn-block">
                    Log in</Button>

            </Form>
        </div>);


}

Upvotes: 2

Views: 5216

Answers (4)

reza.ansarirad
reza.ansarirad

Reputation: 383

try this :

 <BrowserRouter>
<React.StrictMode>
<App />

</React.StrictMode>

Upvotes: 0

Gipfeli
Gipfeli

Reputation: 319

You can either use "Navigate" as a return (It worked for me only in the beginning when a component mounts (no function call)):

import { Navigate } from 'react-router-dom';

function X() {

   if (roles && currentUser && roles.indexOf(currentUser.role) === -1) {
       return (<Navigate to='/notfound'></Navigate>);
   }
   ...
} export { X };

Or you can use "useNavigate". For "useNavigate" you have to create a const first and in a function call you do it with return too -> return navigate("/..."):

import { useNavigate } from 'react-router-dom';
function LoginPage() {
    const navigate = useNavigate();

    const handleLogin = () => {
       if (!(user.username && user.password)) {
           return;
       }
       UserService.login(user)
           .then(data => {
               console.log("login successful")
               return navigate("/");
            }, error => {
               setErrorMessage("Username or password is wrong.");
               console.log("log in failed.")
            });
    }

...
} export { LoginPage };

So Navigate for while component is getting mounted (no function call) and useNavigate for when function calls.

Upvotes: 0

Andrew Samoil
Andrew Samoil

Reputation: 11

In v6 of react-router-dom you would use useNavigate() https://reactnavigation.org/docs/use-navigation/

Upvotes: 0

Zachary Haber
Zachary Haber

Reputation: 11027

In this case, you can use history via useHistory to dynamically change the route.

You get the history object in the component with: const history = useHistory()

Then you can dynamically push or replace the current route using: history.push(ref) or history.replace(ref)

import React, { Component, useState } from "react";
import {Button, Form, FormGroup, Label, Input} from 'reactstrap';
import {useHistory} from 'react-router-dom'
export const Login = () => {
    const [email_or_username, setName] = useState('');
    const [password, setPassword] = useState('');
    const [is_contributor, setContributor] = useState(false);
    const history = useHistory()
    return (           
        <div> 
            <Form className="login-form">
                <h1>
                <div className="text-right">
                    <Button
                        href="/register"
                        className=" btn-dark text-right">
                        sign up
                    </Button>
                </div>
                <span className="font-weight-bold">Mindify</span>
                </h1>
                <FormGroup>
                    <Label>Username or Email</Label>
                    <h2></h2>
                    <Input 
                        value={email_or_username} 
                        placeholder = "Username or Email" 
                        onChange={e => setName(e.target.value)}/>
                </FormGroup>

                <FormGroup>
                    <label>Password</label>
                    <h2></h2>
                    <Input 
                        value={password} 
                        placeholder = "Password"
                        onChange={e => setPassword(e.target.value)}/>
                </FormGroup>

                <FormGroup>
                    <div className="text-center">
                    <Input 
                        type="checkbox"
                        value={is_contributor}
                        onChange={e => setContributor(e.target.checked)}/>
                        Contributor
                    </div>                    
                </FormGroup>


                <Button onClick={async () =>{
                     const login = {email_or_username, password, is_contributor};
                     console.log(JSON.stringify(login));
                     const response = await fetch('http://127.0.0.1:5000/api/login', {
                         method: 'POST',
                         headers:{
                            'Content-Type': 'application/json'
                         },
                         body: JSON.stringify(login)
                     })
                     .then(response => {
                         console.log(response.status);
                         if (response.status === 201) {
                            console.log("Successful Login"); 
                            const ref="/homepage";
                            console.log(ref);
                            //redirect to home page
                            history.push(ref)
                         }
                         else if (response.status === 204) {
                            console.log("Invalid Username or Password or Incorrect Permissions");
                            const ref="/";
                            console.log(ref);
                            // reload login page
                            history.push(ref)
                         }
                     })
                     .catch(error => console.log(error))

                    }}
                    className="btn-lg btn-dark btn-block">
                    Log in</Button>

            </Form>
        </div>);


}

Upvotes: 1

Related Questions