Jeff Bootsholz
Jeff Bootsholz

Reputation: 3068

react button onClick redirect page

I am working on a web application using React and bootstrap. When it comes to applying button onClick, I'm having a hard time to have page being redirect to another. If after a href, I cannot go the another page.

So would you please tell me is there any need for using react-navigation or other to navigate the page using Button onClick ?

import React, { Component } from 'react';
import { Button, Card, CardBody, CardGroup, Col, Container, Input, InputGroup, InputGroupAddon, InputGroupText, Row, NavLink  } from 'reactstrap';
 
class LoginLayout extends Component {
 
  render() {
    return (
 <div className="app flex-row align-items-center">
        <Container>
     ...
                    <Row>
                      <Col xs="6">                      
                        <Button color="primary" className="px-4">
                            Login
                         </Button>
                      </Col>
                      <Col xs="6" className="text-right">
                        <Button color="link" className="px-0">Forgot password?</Button>
                      </Col>
                    </Row>
               ...
        </Container>
      </div>
    );
  }
}
 

Upvotes: 157

Views: 802393

Answers (16)

Mark
Mark

Reputation: 44

This also seems to work well:

<Button color="primary" tag={Link} to={"/some-page"}>

Upvotes: -1

aravind_reddy
aravind_reddy

Reputation: 5466

update:

React Router v6:

import React from 'react';
import { useNavigate } from "react-router-dom";
function LoginLayout() {
  
  let navigate = useNavigate(); 
  const routeChange = () =>{ 
    let path = `newPath`; 
    navigate(path);
  }
  
  return (
     <div className="app flex-row align-items-center">
      <Container>
      ...          
          <Button color="primary" className="px-4"
            onClick={routeChange}
              >
              Login
            </Button>
      ...
       </Container>
    </div>
  );
}}

React Router v5 with hooks:

import React from 'react';
import { useHistory } from "react-router-dom";
function LoginLayout() {
  
  const history = useHistory();
  
  const routeChange = () =>{ 
    let path = `newPath`; 
    history.push(path);
  }

  return (
      <div className="app flex-row align-items-center">
        <Container>
          ...
          <Row>
            <Col xs="6">                      
              <Button color="primary" className="px-4"
                onClick={routeChange}
                  >
                  Login
                </Button>
            </Col>
            <Col xs="6" className="text-right">
              <Button color="link" className="px-0">Forgot password?</Button>
            </Col>
          </Row>
          ...
        </Container>
      </div>
  );
}
export default LoginLayout;

with React Router v5:

import { useHistory } from 'react-router-dom';
import { Button, Card, CardBody, CardGroup, Col, Container, Input, InputGroup, InputGroupAddon, InputGroupText, Row, NavLink  } from 'reactstrap';
    
class LoginLayout extends Component {
  
  routeChange=()=> {
    let path = `newPath`;
    let history = useHistory();
    history.push(path);
  }

  render() {
    return (
      <div className="app flex-row align-items-center">
        <Container>
          ...
          <Row>
            <Col xs="6">                      
              <Button color="primary" className="px-4"
                onClick={this.routeChange}
                  >
                  Login
                </Button>
            </Col>
            <Col xs="6" className="text-right">
              <Button color="link" className="px-0">Forgot password?</Button>
            </Col>
          </Row>
          ...
        </Container>
      </div>
    );
  }
}

export default LoginLayout;

with React Router v4:

import { withRouter } from 'react-router-dom';
import { Button, Card, CardBody, CardGroup, Col, Container, Input, InputGroup, InputGroupAddon, InputGroupText, Row, NavLink  } from 'reactstrap';
    
class LoginLayout extends Component {
  constuctor() {
    this.routeChange = this.routeChange.bind(this);
  }

  routeChange() {
    let path = `newPath`;
    this.props.history.push(path);
  }

  render() {
    return (
      <div className="app flex-row align-items-center">
        <Container>
          ...
          <Row>
            <Col xs="6">                      
              <Button color="primary" className="px-4"
                onClick={this.routeChange}
                  >
                  Login
                </Button>
            </Col>
            <Col xs="6" className="text-right">
              <Button color="link" className="px-0">Forgot password?</Button>
            </Col>
          </Row>
          ...
        </Container>
      </div>
    );
  }
}

export default withRouter(LoginLayout);

Upvotes: 210

hanielchids
hanielchids

Reputation: 57

Make sure to import {Link} from "react-router-dom"; And just hyperlink instead of using a function.

import {Link} from "react-router-dom";

<Button>
   <Link to="/yourRoute">Route Name</Link>
</Button>

Upvotes: 2

Princess
Princess

Reputation: 51

If you already created a class to define the properties of your Button (If you have a button class created already), and you want to call it in another class and link it to another page through a button you created in this new class, just import your "Button" (or the name of your button class) and use the code below:

import React , {useState} from 'react';
import {Button} from '../Button';

function Iworkforbutton() {
const [button] = useState(true);

return (
    <div className='button-class'>
        {button && <Button onClick={()=> window.location.href='/yourPath'}
            I am Button </Button>
    </div>
    )
}

export default Iworkforbutton

Upvotes: 5

Aditya Patnaik
Aditya Patnaik

Reputation: 1776

if you want to redirect to a route on a Click event.

Just do this

In Functional Component

props.history.push('/link')

In Class Component

this.props.history.push('/link')

Example:

<button onClick={()=>{props.history.push('/link')}} >Press</button>

Tested on:

react-router-dom: 5.2.0,

react: 16.12.0

Upvotes: 7

sumit chaudhary
sumit chaudhary

Reputation: 71

If all above methods fails use something like this:

    import React, { Component } from 'react';
    import { Redirect } from "react-router";
    
    export default class Reedirect extends Component {
        state = {
            redirect: false
        }
        redirectHandler = () => {
            this.setState({ redirect: true })
            this.renderRedirect();
        }
        renderRedirect = () => {
            if (this.state.redirect) {
                return <Redirect to='/' />
            }
        }
        render() {
            return (
                <>
                    <button onClick={this.redirectHandler}>click me</button>
                    {this.renderRedirect()}
                </>
            )
        }
    }

Upvotes: 7

Maheshvirus
Maheshvirus

Reputation: 7523

useHistory() from react-router-dom can fix your problem

import React from 'react';
import { useHistory } from "react-router-dom";
function NavigationDemo() {
  const history = useHistory();
  const navigateTo = () => history.push('/componentURL');//eg.history.push('/login');

  return (
   <div>
   <button onClick={navigateTo} type="button" />
   </div>
  );
}
export default NavigationDemo;

Upvotes: 7

Oben Desmond
Oben Desmond

Reputation: 171

First, import it:

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

Then, in function or class:

const history = useHistory();

Finally, you put it in the onClick function:

<Button onClick={()=> history.push("/mypage")}>Click me!</Button>

Upvotes: 13

thenewbieprogrammer
thenewbieprogrammer

Reputation: 11

I was also having the trouble to route to a different view using navlink.

My implementation was as follows and works perfectly;

<NavLink tag='li'>
  <div
    onClick={() =>
      this.props.history.push('/admin/my- settings')
    }
  >
    <DropdownItem className='nav-item'>
      Settings
    </DropdownItem>
  </div>
</NavLink>

Wrap it with a div, assign the onClick handler to the div. Use the history object to push a new view.

Upvotes: 1

Matteus Barbosa
Matteus Barbosa

Reputation: 2725

I was trying to find a way with Redirect but failed. Redirecting onClick is simpler than we think. Just place the following basic JavaScript within your onClick function, no monkey business:

window.location.href="pagelink"

Upvotes: 20

May Noppadol
May Noppadol

Reputation: 648

React Router v5.1.2:

import { useHistory } from 'react-router-dom';
const App = () => {
   const history = useHistory()
   <i className="icon list arrow left"
      onClick={() => {
        history.goBack()
   }}></i>
}

Upvotes: 40

Harsha N Hegde
Harsha N Hegde

Reputation: 373

With React Router v5.1:

import {useHistory} from 'react-router-dom';
import React, {Component} from 'react';
import {Button} from 'reactstrap';
.....
.....
export class yourComponent extends Component {
    .....
    componentDidMount() { 
        let history = useHistory;
        .......
    }

    render() {
        return(
        .....
        .....
            <Button className="fooBarClass" onClick={() => history.back()}>Back</Button>

        )
    }
}

Upvotes: 1

rudresh solanki
rudresh solanki

Reputation: 1015

This can be done very simply, you don't need to use a different function or library for it.

onClick={event =>  window.location.href='/your-href'}

Upvotes: 39

Kareem Khaleel
Kareem Khaleel

Reputation: 85

A very simple way to do this is by the following:

onClick={this.fun.bind(this)}

and for the function:

fun() {
  this.props.history.push("/Home");
}

finlay you need to import withRouter:

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

and export it as:

export default withRouter (comp_name);

Upvotes: 8

Waleed Qidan
Waleed Qidan

Reputation: 1110

Don't use a button as a link. Instead, use a link styled as a button.

<Link to="/signup" className="btn btn-primary">Sign up</Link>

Upvotes: 78

ouni
ouni

Reputation: 3373

A simple click handler on the button, and setting window.location.hash will do the trick, assuming that your destination is also within the app.

You can listen to the hashchange event on window, parse the URL you get, call this.setState(), and you have your own simple router, no library needed.

class LoginLayout extends Component {
    constuctor() {
      this.handlePageChange = this.handlePageChange.bind(this);
      this.handleRouteChange = this.handleRouteChange.bind(this);
      this.state = { page_number: 0 }
    }

  handlePageChange() {
    window.location.hash = "#/my/target/url";
  }

  handleRouteChange(event) {
    const destination = event.newURL;
    // check the URL string, or whatever other condition, to determine
    // how to set internal state.
    if (some_condition) {
      this.setState({ page_number: 1 });
    }
  }

  componentDidMount() {
    window.addEventListener('hashchange', this.handleRouteChange, false);
  }

  render() {
    // @TODO: check this.state.page_number and render the correct page.
    return (
      <div className="app flex-row align-items-center">
        <Container>
          ...
                <Row>
                  <Col xs="6">                      
                    <Button 
                       color="primary"
                       className="px-4"
                       onClick={this.handlePageChange}
                    >
                        Login
                     </Button>
                  </Col>
                  <Col xs="6" className="text-right">
                    <Button color="link" className="px-0">Forgot password </Button>
                  </Col>
                </Row>
           ...
        </Container>
      </div>
    );
  }
}

Upvotes: 1

Related Questions