How to programmatically navigate using React Router?
Asked Answered
N

50

2302

With react-router I can use the Link element to create links which are natively handled by react router.

I see internally it calls this.context.transitionTo(...).

I want to do a navigation. Not from a link, but from a dropdown selection (as an example). How can I do this in code? What is this.context?

I saw the Navigation mixin, but can I do this without mixins?

Nisus answered 26/6, 2015 at 17:38 Comment(0)
S
2558

UPDATE: 2022: React Router v6.6.1 with useNavigate

The useHistory() hook is now deprecated. If you are using React Router 6, the proper way to navigate programmatically is as follows:

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

function HomeButton() {
  const navigate = useNavigate();

  function handleClick() {
    navigate("/home");
  }

  return (
    <button type="button" onClick={handleClick}>
      Go home
    </button>
  );
}

React Router v5.1.0 with hooks

There is a new useHistory hook in React Router >5.1.0 if you are using React >16.8.0 and functional components.

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

function HomeButton() {
  const history = useHistory();

  function handleClick() {
    history.push("/home");
  }

  return (
    <button type="button" onClick={handleClick}>
      Go home
    </button>
  );
}

React Router v4

With v4 of React Router, there are three approaches that you can take to programmatic routing within components.

  1. Use the withRouter higher-order component.
  2. Use composition and render a <Route>
  3. Use the context.

React Router is mostly a wrapper around the history library. history handles interaction with the browser's window.history for you with its browser and hash histories. It also provides a memory history which is useful for environments that don't have a global history. This is particularly useful in mobile app development (react-native) and unit testing with Node.

A history instance has two methods for navigating: push and replace. If you think of the history as an array of visited locations, push will add a new location to the array and replace will replace the current location in the array with the new one. Typically you will want to use the push method when you are navigating.

In earlier versions of React Router, you had to create your own history instance, but in v4 the <BrowserRouter>, <HashRouter>, and <MemoryRouter> components will create a browser, hash, and memory instances for you. React Router makes the properties and methods of the history instance associated with your router available through the context, under the router object.

1. Use the withRouter higher-order component

The withRouter higher-order component will inject the history object as a prop of the component. This allows you to access the push and replace methods without having to deal with the context.

import { withRouter } from 'react-router-dom'
// this also works with react-router-native

const Button = withRouter(({ history }) => (
  <button
    type='button'
    onClick={() => { history.push('/new-location') }}
  >
    Click Me!
  </button>
))

2. Use composition and render a <Route>

The <Route> component isn't just for matching locations. You can render a pathless route and it will always match the current location. The <Route> component passes the same props as withRouter, so you will be able to access the history methods through the history prop.

import { Route } from 'react-router-dom'

const Button = () => (
  <Route render={({ history}) => (
    <button
      type='button'
      onClick={() => { history.push('/new-location') }}
    >
      Click Me!
    </button>
  )} />
)

3. Use the context*

But you probably should not

The last option is one that you should only use if you feel comfortable working with React's context model (React's Context API is stable as of v16).

const Button = (props, context) => (
  <button
    type='button'
    onClick={() => {
      // context.history.push === history.push
      context.history.push('/new-location')
    }}
  >
    Click Me!
  </button>
)

// you need to specify the context type so that it
// is available within the component
Button.contextTypes = {
  history: React.PropTypes.shape({
    push: React.PropTypes.func.isRequired
  })
}

1 and 2 are the simplest choices to implement, so for most use cases, they are your best bets.

Sloane answered 8/2, 2017 at 18:39 Comment(9)
I tried to use method 1 in this way withRouter(( { history } ) => { console.log("hhhhhhhh"); history.push('/bets') }); But it never worked with router 4Hellish
WHAT!? I can just use withRouter instead of passing history down through all of my components?? Gahh I need to spend more time reading docs...Enrico
How can you just run history.push('/new-location') without attaching that behaviour to a Button or other DOM element?Heracles
context isn't experimental anymore as of react 16.Resiniferous
Update: for those who use eact-router-dom v6 should use useNavigate() instead of useHistory(). See the following answer for more detail. https://mcmap.net/q/41047/-attempted-import-error-39-usehistory-39-is-not-exported-from-39-react-router-dom-39Defloration
Only a update. In v6 you need use useNavegate hook. import { useNavigate } from 'react-router-dom'; const navigate = useNavigate(); navigate('URL')Wicks
@Dmitry When using the history method, your <Route/> tags must all be wrapped inside the <Router></Router> tag. Make sure there aren't things like a MaterialUI CSS tag in the way messing up scope. (in the App.js file)Regionalism
React Router v6 replaced useHistory with useNavigate, which is obviously a more delarative/appropriate name for the hook. reactrouter.com/docs/en/v6/api#usenavigateAmerind
withRouter is deprecated as it breaks with memoization.Excisable
I
1424

React-Router v6+ Answer

TL;DR: You can use the new useNavigate hook.

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

function Component() {
  let navigate = useNavigate();
  // Somewhere in your code, e.g. inside a handler:
  navigate("/posts"); 
}

The useNavigate hook returns a function which can be used for programmatic navigation.

Example from the react router documentation

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

function SignupForm() {
  let navigate = useNavigate();

  async function handleSubmit(event) {
    event.preventDefault();
    await submitForm(event.target);
    navigate("../success", { replace: true });
    // replace: true will replace the current entry in 
    // the history stack instead of adding a new one.

  }

  return <form onSubmit={handleSubmit}>{/* ... */}</form>;
}

React-Router 5.1.0+ Answer (using hooks and React >16.8)

You can use the useHistory hook on Functional Components and Programmatically navigate:

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

function HomeButton() {
  let history = useHistory();
  // use history.push('/some/path') here
};

React-Router 4.0.0+ Answer

In 4.0 and above, use the history as a prop of your component.

class Example extends React.Component {
   // use `this.props.history.push('/some/path')` here
};

NOTE: this.props.history does not exist in the case your component was not rendered by <Route>. You should use <Route path="..." component={YourComponent}/> to have this.props.history in YourComponent

React-Router 3.0.0+ Answer

In 3.0 and above, use the router as a prop of your component.

class Example extends React.Component {
   // use `this.props.router.push('/some/path')` here
};

React-Router 2.4.0+ Answer

In 2.4 and above, use a higher order component to get the router as a prop of your component.

import { withRouter } from 'react-router';

class Example extends React.Component {
   // use `this.props.router.push('/some/path')` here
};

// Export the decorated class
var DecoratedExample = withRouter(Example);

// PropTypes
Example.propTypes = {
  router: React.PropTypes.shape({
    push: React.PropTypes.func.isRequired
  }).isRequired
};

React-Router 2.0.0+ Answer

This version is backwards compatible with 1.x so there's no need to an Upgrade Guide. Just going through the examples should be good enough.

That said, if you wish to switch to the new pattern, there's a browserHistory module inside the router that you can access with

import { browserHistory } from 'react-router'

Now you have access to your browser history, so you can do things like push, replace, etc... Like:

browserHistory.push('/some/path')

Further reading: Histories and Navigation


React-Router 1.x.x Answer

I will not go into upgrading details. You can read about that in the Upgrade Guide

The main change about the question here is the change from Navigation mixin to History. Now it's using the browser historyAPI to change route so we will use pushState() from now on.

Here's an exemple using Mixin:

var Example = React.createClass({
  mixins: [ History ],
  navigateToHelpPage () {
    this.history.pushState(null, `/help`);
  }
})

Note that this History comes from rackt/history project. Not from React-Router itself.

If you don't want to use Mixin for some reason (maybe because of ES6 class), then you can access the history that you get from the router from this.props.history. It will be only accessible for the components rendered by your Router. So, if you want to use it in any child components it needs to be passed down as an attribute via props.

You can read more about the new release at their 1.0.x documentation

Here is a help page specifically about navigating outside your component

It recommends grabbing a reference history = createHistory() and calling replaceState on that.

React-Router 0.13.x Answer

I got into the same problem and could only find the solution with the Navigation mixin that comes with react-router.

Here's how I did it

import React from 'react';
import {Navigation} from 'react-router';

let Authentication = React.createClass({
  mixins: [Navigation],

  handleClick(e) {
    e.preventDefault();

    this.transitionTo('/');
  },

  render(){
    return (<div onClick={this.handleClick}>Click me!</div>);
  }
});

I was able to call transitionTo() without the need to access .context

Or you could try the fancy ES6 class

import React from 'react';

export default class Authentication extends React.Component {
  constructor(props) {
    super(props);
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick(e) {
    e.preventDefault();

    this.context.router.transitionTo('/');
  }

  render(){
    return (<div onClick={this.handleClick}>Click me!</div>);
  }
}

Authentication.contextTypes = {
  router: React.PropTypes.func.isRequired
};

React-Router-Redux

Note: if you're using Redux, there is another project called React-Router-Redux that gives you redux bindings for ReactRouter, using somewhat the same approach that React-Redux does

React-Router-Redux has a few methods available that allow for simple navigating from inside action creators. These can be particularly useful for people that have existing architecture in React Native, and they wish to utilize the same patterns in React Web with minimal boilerplate overhead.

Explore the following methods:

  • push(location)
  • replace(location)
  • go(number)
  • goBack()
  • goForward()

Here is an example usage, with Redux-Thunk:

./actioncreators.js

import { goBack } from 'react-router-redux'

export const onBackPress = () => (dispatch) => dispatch(goBack())

./viewcomponent.js

<button
  disabled={submitting}
  className="cancel_button"
  onClick={(e) => {
    e.preventDefault()
    this.props.onBackPress()
  }}
>
  CANCEL
</button>
Interjection answered 26/6, 2015 at 17:49 Comment(3)
I was hoping useNavigate was the solution, but version 6.2.1 it seems to be ignoring the { replace: true } and doesn't refresh the page.Numbing
The docs aren't clear about the purpose or expected behavior of including the second optional param replace: state.Anvil
Is there a solution that doesn't use hooks?Outpoint
C
553

React-Router v2

For the most recent release (v2.0.0-rc5), the recommended navigation method is by directly pushing onto the history singleton. You can see that in action in the Navigating outside of Components doc.

Relevant excerpt:

import { browserHistory } from 'react-router';
browserHistory.push('/some/path');

If using the newer react-router API, you need to make use of the history from this.props when inside of components so:

this.props.history.push('/some/path');

It also offers pushState but that is deprecated per logged warnings.

If using react-router-redux, it offers a push function you can dispatch like so:

import { push } from 'react-router-redux';
this.props.dispatch(push('/some/path'));

However this may be only used to change the URL, not to actually navigate to the page.

Canter answered 18/1, 2016 at 20:32 Comment(1)
Don't forget that the newer API doesn't use import { browserHistory } from './react-router' but instead creates history using import createBrowserHistory from 'history/lib/createBrowserHistory'. Later on, you can access history from the components props: this.props.history('/some/path')Herophilus
H
90

React-Router 4.x answer

On my end, I like to have a single history object that I can carry even outside components. I like to have a single history.js file that I import on demand, and just manipulate it.

You just have to change BrowserRouter to Router, and specify the history prop. This doesn't change anything for you, except that you have your own history object that you can manipulate as you want.

You need to install history, the library used by react-router.

Example usage, ES6 notation:

history.js

import createBrowserHistory from 'history/createBrowserHistory'
export default createBrowserHistory()

BasicComponent.js

import React, { Component } from 'react';
import history from './history';

class BasicComponent extends Component {

    goToIndex(e){
        e.preventDefault();
        history.push('/');
    }

    render(){
        return <a href="#" onClick={this.goToIndex}>Previous</a>;
    }
}

If you have to navigate from a component that is actually rendered from a Route component, you can also access history from props, like that:

BasicComponent.js

import React, { Component } from 'react';

class BasicComponent extends Component {

    navigate(e){
        e.preventDefault();
        this.props.history.push('/url');
    }

    render(){
        return <a href="#" onClick={this.navigate}>Previous</a>;
    }
}
Humanly answered 6/6, 2017 at 22:14 Comment(0)
A
86

Here's how you do this with react-router v2.0.0 with ES6. react-router has moved away from mixins.

import React from 'react';

export default class MyComponent extends React.Component {
  navigateToPage = () => {
    this.context.router.push('/my-route')
  };

  render() {
    return (
      <button onClick={this.navigateToPage}>Go!</button>
    );
  }
}

MyComponent.contextTypes = {
  router: React.PropTypes.object.isRequired
}
Ambassador answered 22/1, 2016 at 20:46 Comment(0)
U
77

For this one, who does not control the server side and because of this is using hash router v2:

Place your history into separate file (e.g. app_history.js ES6):

import { useRouterHistory } from 'react-router'
import { createHashHistory } from 'history'
const appHistory = useRouterHistory(createHashHistory)({ queryKey: false });

export default appHistory;

And use it everywhere!

Your entry point for react-router (app.js ES6):

import React from 'react'
import { render } from 'react-dom'
import { Router, Route, Redirect } from 'react-router'
import appHistory from './app_history'
...
const render((
  <Router history={appHistory}>
  ...
  </Router>
), document.querySelector('[data-role="app"]'));

Your navigation inside any component (ES6):

import appHistory from '../app_history'
...
ajaxLogin('/login', (err, data) => {
  if (err) {
    console.error(err); // login failed
  } else {
    // logged in
    appHistory.replace('/dashboard'); // or .push() if you don't need .replace()
  }
})
Uvulitis answered 19/3, 2016 at 12:59 Comment(0)
B
69

React Router v6

I haven't touched React in a while, but want to thank and highlight the comment below by Shimrit Snapir:

on React-Router 6.0 <Redirect /> changed to <Navigate />

React Router V4

tl:dr;

if (navigate) {
  return <Redirect to="/" push={true} />
}

The simple and declarative answer is that you need to use <Redirect to={URL} push={boolean} /> in combination with setState()

push: boolean - when true, redirecting will push a new entry onto the history instead of replacing the current one.


import { Redirect } from 'react-router'

class FooBar extends React.Component {
  state = {
    navigate: false
  }

  render() {
    const { navigate } = this.state

    // Here is the important part
    if (navigate) {
      return <Redirect to="/" push={true} />
    }
   // ^^^^^^^^^^^^^^^^^^^^^^^

    return (
      <div>
        <button onClick={() => this.setState({ navigate: true })}>
          Home
        </button>
      </div>
    )
  }
}

A full example is here. Read more here.

PS. The example uses ES7+ Property Initializers to initialise state. Look here as well, if you're interested.

Becca answered 22/11, 2017 at 10:59 Comment(0)
O
57

Warning: this answer covers only ReactRouter versions before 1.0

I will update this answer with 1.0.0-rc1 use cases after!

You can do this without mixins too.

let Authentication = React.createClass({
  contextTypes: {
    router: React.PropTypes.func
  },
  handleClick(e) {
    e.preventDefault();
    this.context.router.transitionTo('/');
  },
  render(){
    return (<div onClick={this.handleClick}>Click me!</div>);
  }
});

The gotcha with contexts is that it is not accessible unless you define the contextTypes on the class.

As for what is context, it is an object, like props, that are passed down from parent to child, but it is passed down implicitly, without having to redeclare props each time. See https://www.tildedave.com/2014/11/15/introduction-to-contexts-in-react-js.html

Olds answered 30/6, 2015 at 6:14 Comment(0)
P
50

Here's the simplest and cleanest way to do it, circa current React-Router 3.0.0 and ES6:

React-Router 3.x.x with ES6:

import { withRouter } from 'react-router';

class Example extends React.Component {
   // use `this.props.router.push('/some/path')` here
};

// Export the decorated class
export default withRouter(Example);

Or, if it's not your default class, export like:

withRouter(Example);
export { Example };

Note that in 3.x.x, the <Link> component itself is using router.push, so you can pass it anything you would pass the <Link to= tag, like:

   this.props.router.push({pathname: '/some/path', query: {key1: 'val1', key2: 'val2'})'
Pops answered 30/11, 2016 at 14:2 Comment(0)
C
42

To do the navigation programmatically, you need to push a new history to the props.history in your component, so something like this can do the work for you:

//using ES6
import React from 'react';

class App extends React.Component {

  constructor(props) {
    super(props)
    this.handleClick = this.handleClick.bind(this)
  }

  handleClick(e) {
    e.preventDefault()
    /* Look at here, you can add it here */
    this.props.history.push('/redirected');
  }

  render() {
    return (
      <div>
        <button onClick={this.handleClick}>
          Redirect!!!
        </button>
      </div>
    )
  }
}

export default App;
Charily answered 15/5, 2017 at 8:53 Comment(1)
Can you please take a look #77540662Voluntaryism
T
41

For ES6 + React components, the following solution worked for me.

I followed Felippe skinner, but added an end to end solution to help beginners like me.

Below are the versions I used:

"react-router": "^2.7.0"

"react": "^15.3.1"

Below is my react component where I used programmatic navigation using react-router:

import React from 'react';

class loginComp extends React.Component {
   constructor( context) {
    super(context);
    this.state = {
      uname: '',
      pwd: ''
    };
  }

  redirectToMainPage(){
        this.context.router.replace('/home');
  }

  render(){
    return <div>
           // skipping html code 
             <button onClick={this.redirectToMainPage.bind(this)}>Redirect</button>
    </div>;
  }
};

 loginComp.contextTypes = {
    router: React.PropTypes.object.isRequired
 }

 module.exports = loginComp;

Below is the configuration for my router:

 import { Router, Route, IndexRedirect, browserHistory } from 'react-router'

 render(<Router history={browserHistory}>
          <Route path='/' component={ParentComp}>
            <IndexRedirect to = "/login"/>
            <Route path='/login' component={LoginComp}/>
            <Route path='/home' component={HomeComp}/>
            <Route path='/repair' component={RepairJobComp} />
            <Route path='/service' component={ServiceJobComp} />
          </Route>
        </Router>, document.getElementById('root'));
Toddler answered 12/9, 2016 at 22:0 Comment(0)
A
39

It may not be the best approach but... Using react-router v4, the following TypeScript code could give an idea for some.

In the rendered component below, e.g. LoginPage, router object is accessible and just call router.transitionTo('/homepage') to navigate.

Navigation code was taken from.

"react-router": "^4.0.0-2", "react": "^15.3.1",

import Router from 'react-router/BrowserRouter';
import { History } from 'react-history/BrowserHistory';
import createHistory from 'history/createBrowserHistory';
const history = createHistory();

interface MatchWithPropsInterface {
  component: typeof React.Component,
  router: Router,
  history: History,
  exactly?: any,
  pattern: string
}

class MatchWithProps extends React.Component<MatchWithPropsInterface,any> {
  render() {
    return(
      <Match {...this.props} render={(matchProps) => (
             React.createElement(this.props.component, this.props)

        )}
       />
    )
  }
}

ReactDOM.render(
    <Router>
      {({ router }) => (
        <div>
          <MatchWithProps exactly pattern="/" component={LoginPage} router={router} history={history} />
          <MatchWithProps pattern="/login" component={LoginPage} router={router} history={history} />
          <MatchWithProps pattern="/homepage" component={HomePage} router={router} history={history} />
          <Miss component={NotFoundView} />
        </div>
      )}
    </Router>,

   document.getElementById('app')
);
Australorp answered 27/9, 2016 at 21:32 Comment(0)
C
39

In React Router v4, I follow these two ways to route programmatically.

  1. this.props.history.push("/something/something")
  2. this.props.history.replace("/something/something")

Number two

Replaces the current entry on the history stack

To get history in props you may have to wrap your component with

withRouter

In React Router v6

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

function Invoices() {
  let navigate = useNavigate();
  return (
    <div>
      <NewInvoiceForm
        onSubmit={async event => {
          let newInvoice = await createInvoice(event.target);
          navigate(`/invoices/${newInvoice.id}`);
        }}
      />
    </div>
  );
}

Getting Started with React Router v6

Chromaticness answered 14/8, 2018 at 6:33 Comment(0)
D
29

With React-Router v4 on the horizon, there is now a new way of doing this.

import { MemoryRouter, BrowserRouter } from 'react-router';

const navigator = global && global.navigator && global.navigator.userAgent;
const hasWindow = typeof window !== 'undefined';
const isBrowser = typeof navigator !== 'undefined' && navigator.indexOf('Node.js') === -1;
const Router = isBrowser ? BrowserRouter : MemoryRouter;

<Router location="/page-to-go-to"/>

react-lego is an example app that shows how to use/update react-router and it includes example functional tests which navigate the app.

Dollie answered 15/9, 2016 at 8:0 Comment(1)
This is great for navigating from the render function, though I wonder how to navigate from something like a lifecycle hook, or redux?Benedetto
B
29

In React-Router v4 and ES6

You can use withRouter and this.props.history.push.

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

class Home extends Component {

    componentDidMount() {
        this.props.history.push('/redirect-to');
    }
}

export default withRouter(Home);
Battiste answered 17/9, 2017 at 5:54 Comment(0)
W
29

To use withRouter with a class-based component, try something like this below. Don't forget to change the export statement to use withRouter:

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

class YourClass extends React.Component {
  yourFunction = () => {
    doSomeAsyncAction(() =>
      this.props.history.push('/other_location')
    )
  }

  render() {
    return (
      <div>
        <Form onSubmit={ this.yourFunction } />
      </div>
    )
  }
}

export default withRouter(YourClass);
Wheeze answered 28/5, 2018 at 9:2 Comment(0)
G
26

Based on the previous answers from José Antonio Postigo and Ben Wheeler:

The novelty? Is to be written in TypeScript and uses decorators or a static property/field

import * as React from "react";
import Component = React.Component;
import { withRouter } from "react-router";

export interface INavigatorProps {
    router?: ReactRouter.History.History;
}

/**
 * Note: goes great with mobx
 * @inject("something") @withRouter @observer
 */
@withRouter
export class Navigator extends Component<INavigatorProps, {}>{
    navigate: (to: string) => void;
    constructor(props: INavigatorProps) {
        super(props);
        let self = this;
        this.navigate = (to) => self.props.router.push(to);
    }
    render() {
        return (
            <ul>
                <li onClick={() => this.navigate("/home")}>
                    Home
                </li>
                <li onClick={() => this.navigate("/about")}>
                    About
                </li>
            </ul>
        )
    }
}

/**
 * Non decorated
 */
export class Navigator2 extends Component<INavigatorProps, {}> {

    static contextTypes = {
        router: React.PropTypes.object.isRequired,
    };

    navigate: (to: string) => void;
    constructor(props: INavigatorProps, context: any) {
        super(props, context);
        let s = this;
        this.navigate = (to) =>
            s.context.router.push(to);
    }
    render() {
        return (
            <ul>
                <li onClick={() => this.navigate("/home")}>
                    Home
                </li>
                <li onClick={() => this.navigate("/about")}>
                    About
                </li>
            </ul>
        )
    }
}

with whatever npm installed today.

"react-router": "^3.0.0" and
"@types/react-router": "^2.0.41"

Gnu answered 23/12, 2016 at 8:15 Comment(0)
T
23

For those who are already using React Router v6, this can be done using useNavigate hook provided by react-router.

Navigation with this hook is pretty simple:

import { generatePath, useNavigate } from 'react-router';

navigate(-1); // navigates back
navigate('/my/path'); // navigates to a specific path
navigate(generatePath('my/path/:id', { id: 1 })); // navigates to a dynamic path, generatePath is very useful for url replacements
Trotta answered 22/11, 2021 at 21:43 Comment(0)
T
21

For Latest react-router-dom v6

useHistory() is replaced with useNavigate().

You need to use:

import { useNavigate } from 'react-router-dom';
const navigate = useNavigate();
navigate('/your-page-link');
Terminus answered 12/2, 2022 at 16:30 Comment(0)
A
19

React Router v6 with hooks

import {useNavigate} from 'react-router-dom';
let navigate = useNavigate();
navigate('home');

And to move across the browser history,

navigate(-1); ---> Go back
navigate(1);  ---> Go forward
navigate(-2); ---> Move two steps backward.
Alanalana answered 18/6, 2020 at 14:56 Comment(0)
K
17

With the current React version (15.3), this.props.history.push('/location'); worked for me, but it showed the following warning:

browser.js:49 Warning: [react-router] props.history and context.history are deprecated. Please use context.router.

and I solved it using context.router like this:

import React from 'react';

class MyComponent extends React.Component {

    constructor(props) {
        super(props);
        this.backPressed = this.backPressed.bind(this);
    }

    backPressed() {
        this.context.router.push('/back-location');
    }

    ...
}

MyComponent.contextTypes = {
    router: React.PropTypes.object.isRequired
};

export default MyComponent;
Katy answered 29/9, 2016 at 12:4 Comment(0)
T
16

If you are using hash or browser history then you can do

hashHistory.push('/login');
browserHistory.push('/login');
Tagmemics answered 18/8, 2017 at 10:50 Comment(0)
W
14

React-Router V4

If you're using version 4 then you can use my library (shameless plug) where you simply dispatch an action and everything just works!

dispatch(navigateTo("/aboutUs"));

trippler

Wrack answered 3/11, 2016 at 17:43 Comment(0)
I
13

Those who are facing issues in implementing this in React Router v4.

Here is a working solution for navigating through the React app from redux actions.

File history.js

import createHistory from 'history/createBrowserHistory'

export default createHistory()

Files App.js/Route.jsx

import { Router, Route } from 'react-router-dom'
import history from './history'
...
<Router history={history}>
 <Route path="/test" component={Test}/>
</Router>

File *another_file.js or redux file

import history from './history'

history.push('/test') // This should change the URL and rerender Test component

All thanks to this comment on GitHub: ReactTraining issues comment

Invar answered 30/11, 2018 at 7:40 Comment(0)
T
12

You can also use the useHistory hook in a stateless component. Example from the documentation:

import { useHistory } from "react-router"

function HomeButton() {
  const history = useHistory()

  return (
    <button type="button" onClick={() => history.push("/home")}>
      Go home
    </button>
  )
}

Note: Hooks were added in [email protected] and require react@>=16.8

Tropism answered 5/10, 2019 at 19:23 Comment(1)
Good call, could you note which version of react-router and react that refers to? This is a new change that wasn't always availableNisus
M
10

Programmatically navigate in class-based components.

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

class MyComponent extends React.Component{
    state = {rpath: null}

    const goTo = (path) => this.setState({rpath: path});

    render(){
        if(this.state.rpath){
            return <Redirect to={this.state.rpath}/>
        }
        .....
        .....
    }
}
Manteltree answered 15/9, 2020 at 6:28 Comment(0)
S
9

In my answer there are three different ways to redirect programmatically to a route. Some of the solutions has been presented already, but the following ones focused only for functional components with an additional demo application.

Using the following versions:

react: 16.13.1

react-dom: 16.13.1

react-router: 5.2.0

react-router-dom: 5.2.0

typescript: 3.7.2

Configuration:

So first of all the solution is using HashRouter, configured as follows:

<HashRouter>
    // ... buttons for redirect

    <Switch>
      <Route exact path="/(|home)" children={Home} />
      <Route exact path="/usehistory" children={UseHistoryResult} />
      <Route exact path="/withrouter" children={WithRouterResult} />
      <Route exact path="/redirectpush" children={RedirectPushResult} />
      <Route children={Home} />
    </Switch>
</HashRouter>

From the documentation about <HashRouter>:

A <Router> that uses the hash portion of the URL (i.e. window.location.hash) to keep your UI in sync with the URL.

Solutions:

  1. Using <Redirect> to push using useState:

Using in a functional component (RedirectPushAction component from my repository) we can use useState to handle redirect. The tricky part is once the redirection happened, we need to set the redirect state back to false. By using setTimeOut with 0 delay we are waiting until React commits Redirect to the DOM and then getting back the button in order to use it the next time.

Please find my example below:

const [redirect, setRedirect] = useState(false);
const handleRedirect = useCallback(() => {
    let render = null;
    if (redirect) {
        render = <Redirect to="/redirectpush" push={true} />

        // In order wait until committing to the DOM
        // and get back the button for clicking next time
        setTimeout(() => setRedirect(false), 0);
    }
    return render;
}, [redirect]);

return <>
    {handleRedirect()}
    <button onClick={() => setRedirect(true)}>
        Redirect push
    </button>
</>

From <Redirect> documentation:

Rendering a <Redirect> will navigate to a new location. The new location will override the current location in the history stack, like server-side redirects (HTTP 3xx) do.

  1. Using useHistory hook:

In my solution there is a component called UseHistoryAction which represents the following:

let history = useHistory();

return <button onClick={() => { history.push('/usehistory') }}>
    useHistory redirect
</button>

The useHistory hook gives us access to the history object which helps us programmatically navigate or change routes.

  1. Using withRouter, get the history from props:

Created one component called WithRouterAction, displays as below:

const WithRouterAction = (props:any) => {
    const { history } = props;

    return <button onClick={() => { history.push('/withrouter') }}>
        withRouter redirect
    </button>
}

export default withRouter(WithRouterAction);

Reading from withRouter documentation:

You can get access to the history object's properties and the closest <Route>'s match via the withRouter higher-order component. withRouter will pass updated match, location, and history props to the wrapped component whenever it renders.

Demo:

For better representation I have built a GitHub repository with these examples, please find it below:

React Router Programmatically Redirect Examples

Saddlery answered 24/11, 2019 at 15:4 Comment(0)
Y
8

The right answer was for me at the time of writing

this.context.router.history.push('/');

But you need to add PropTypes to your component

Header.contextTypes = {
  router: PropTypes.object.isRequired
}
export default Header;

Don't forget to import PropTypes

import PropTypes from 'prop-types';
Yates answered 2/2, 2018 at 1:25 Comment(0)
E
8

If you happen to pair RR4 with redux through react-router-redux, using the routing action creators from react-router-redux is an option as well.

import { push, replace, ... } from 'react-router-redux'

class WrappedComponent extends React.Component {
  handleRedirect(url, replaceState = true) {
    replaceState
      ? this.props.dispatch(replace(url))
      : this.props.dispatch(push(url))
  }
  render() { ... }
}

export default connect(null)(WrappedComponent)

If you use redux thunk/saga to manage async flow, import the above action creators in redux actions and hook to React components using mapDispatchToProps might be better.

Eleanoreleanora answered 7/5, 2018 at 6:43 Comment(0)
D
8

Try React Hook Router instead, "the modern alternative to react-router":

import { useRoutes, usePath, A} from "hookrouter";

To answer the OP's question about linking through a select box, you can do it:

navigate('/about');

Updated answer

I think React Hook Router was a good starter kit and helped me learn about routing, but I have since updated to React Router for its history and query parameter handling.

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


const Component = (props) => {
    const history = useHistory();

    // Programmatically navigate
    history.push(newUrlString);
}

You push where you want to navigate into the location.history.

Disorderly answered 15/1, 2020 at 18:44 Comment(0)
S
7

Maybe not the best solution, but it gets the job done:

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

// Create functional component Post
export default Post = () => (
    <div className="component post">

        <button className="button delete-post" onClick={() => {
            // ... delete post
            // then redirect, without page reload, by triggering a hidden Link
            document.querySelector('.trigger.go-home').click();
        }}>Delete Post</button>

        <Link to="/" className="trigger go-home hidden"></Link>

    </div>
);

Basically, logic tied to one action (in this case a post deletion) will end up calling a trigger for redirect. This is not ideal, because you will add a DOM node 'trigger' to your markup just so you can conveniently call it when needed. Also, you will directly interact with the DOM, which in a React component may not be desired.

Still, this type of redirect is not required that often. So one or two extra, hidden links in your component markup would not hurt that much, especially if you give them meaningful names.

Scorify answered 7/12, 2017 at 17:26 Comment(0)
R
7

This worked for me, and special imports were not needed:

<input 
  type="button" 
  name="back" 
  id="back" 
  class="btn btn-primary" 
  value="Back" 
  onClick={() => { this.props.history.goBack() }} 
/>
Referendum answered 23/8, 2019 at 7:34 Comment(0)
S
7

Just use useNavigate for simplicity with the latest version of react

Newfile.js

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

const Newfile = () => {
    const navigate = useNavigate();
   
    ....

    navigate("yourdesiredlocation");

    ....
}

export default Newfile;

Use useNavigate feature like above in your code.

Schuyler answered 2/3, 2022 at 14:37 Comment(0)
M
5

For React Router v4+

Assuming that you won't be needing to navigate during the initial render itself (for which you can use <Redirect> component), this is what we are doing in our application.

Define an empty route which returns null. This will allow you to get the access to the history object. You need to do this at the top level where your Router is defined.

Now you can do all the things that can be done on history, like history.push(), history.replace(), history.go(-1), etc.!

import React from 'react';
import { HashRouter, Route } from 'react-router-dom';

let routeHistory = null;

export function navigateTo(path) {
  if(routeHistory !== null) {
    routeHistory.push(path);
  }
}

export default function App(props) {
  return (
    <HashRouter hashType="noslash">
      <Route
        render={({ history }) => {
          routeHistory = history;
          return null;
        }}
      />
      {/* Rest of the App */}
    </HashRouter>
  );
}
Merralee answered 23/5, 2019 at 8:57 Comment(0)
M
4

react-router-dom: 5.1.2

  • This site has 3 pages, all of which are rendered dynamically in the browser.

  • Although the page does not ever refresh, notice how React Router keeps the URL up to date as you navigate through the site. This preserves the browser history, making sure things like the back button and bookmarks work properly

  • A Switch looks through all its children elements and renders the first one whose path matches the current URL. Use a any time you have multiple routes, but you want only one of them to render at a time

import React from "react";
import {
  BrowserRouter as Router,
  Switch,
  Route,
  Link
} from "react-router-dom";



export default function BasicExample() {
  return (
    <Router>
      <div>
        <ul>
          <li>
            <Link to="/">Home</Link>
          </li>
          <li>
            <Link to="/about">About</Link>
          </li>
          <li>
            <Link to="/dashboard">Dashboard</Link>
          </li>
        </ul>

        <hr />

        <Switch>
          <Route exact path="/">
            <Home />
          </Route>
          <Route path="/about">
            <About />
          </Route>
          <Route path="/dashboard">
            <Dashboard />
          </Route>
        </Switch>
      </div>
    </Router>
  );
}

// You can think of these components as "pages"
// in your app.

function Home() {
  return (
    <div>
      <h2>Home</h2>
    </div>
  );
}

function About() {
  return (
    <div>
      <h2>About</h2>
    </div>
  );
}

function Dashboard() {
  return (
    <div>
      <h2>Dashboard</h2>
    </div>
  );
}```
Mirage answered 28/12, 2019 at 8:50 Comment(2)
Welcome to SO! When you reply to a question with so many answers, try to show the benefits of yours.Buskirk
This also doesn't answer the question which is how to do it programmatically from imperative js, not with markup.Nisus
D
4

Using the "useHistory" hook is the best option if you're using a newer version of React.

Dissonancy answered 1/10, 2020 at 6:21 Comment(0)
O
4

This is already mentioned that we can navigate in the last update React Router V6 (doesn't include useHistory) using useNavigate()

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

const myComponent = () => {
  const navigate = useNavigate();
  navigate('my_url');
  ...
}

But what I could not find here is calling navigate out of React component like navigating page inside redux-saga function to another page. Just in case, if you have the same question, here is what I found.

In your root component (I call that <App />)

import { useNavigate } from 'react-router-dom';
import useBus from 'use-bus';

const App = () => {
  const navigate = useNavigate();
  useBus('@@ui/navigate', (action) => navigate(action.payload.url), []);
  ...
}

Out of React component (in my case redux-saga function)

import { dispatch } from 'use-bus';

dispatch({ type: '@@ui/navigate', payload: { url: '/404' } });

Hope it's helpful!

Oakum answered 23/5, 2021 at 2:7 Comment(0)
M
3

Those are couple of ways you can use for this case, I hope you benifit from them.

There are a few ways to do programmatic routing in React.js using React Router without using the Link component.

1. Use the useNavigate hook.

The useNavigate hook allows you to navigate to a different route programmatically. To use it, you first need to import it from React Router:

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

Then, you can call the useNavigate hook inside of your component to get a function that you can use to navigate to a different route:

const navigate = useNavigate();

To navigate to a different route, simply call the navigate function with the path of the route that you want to navigate to:

navigate('/new-page');

You can also pass additional options to the navigate function, such as the state of the route and whether or not to replace the current history entry:

navigate('/new-page', {
  state: {
    message: 'Hello from the new page!',
  },
  replace: true,
});

2. Use the history object.

The history object is a global object that allows you to manipulate the browser's history stack. You can use it to navigate to a different route, go back or forward in history, and more.

To access the history object, you can use the useHistory hook from React Router:

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

Then, you can call the push(), replace(), and goBack() methods on the history object to navigate to different routes:

history.push('/new-page');
history.replace('/new-page');
history.goBack();

3. Use the <Navigate> component.

The <Navigate> component is a new component in React Router v6 that allows you to navigate to a different route programmatically. To use it, you first need to import it from React Router:

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

Then, you can use the <Navigate> component in your component like this:

<Navigate to='/new-page' />

This will navigate to the /new-page route immediately.

Which method you choose to use for programmatic routing will depend on your specific needs and preferences. However, all of these methods are valid and can be used to navigate to different routes programmatically without using the Link component.

Here is an example of how to use the useNavigate hook to programmatically navigate to a different route when a button is clicked:

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

const Button = () => {
  const navigate = useNavigate();

  const handleClick = () => {
    navigate('/new-page');
  };

  return (
    <button onClick={handleClick}>
      Navigate to new page
    </button>
  );
};

export default Button;

This will navigate to the /new-page route when the button is clicked.

I hope this helps!

Megara answered 8/10, 2023 at 21:20 Comment(1)
why the const navigate = useNavigate(); Seems to me it should just be UseNavigate('/new-page').Susann
D
2

You can try the onClick event in React and call a function to redirect to the specified location using useNavigate hook of React Router. You can directly use callback function in the onClick handler rather than specifying a different function. You first need to install react router DOM.

npm i react-router-dom

Try the below code

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

const Page = () => {
  const navigate = useNavigate();

  return (
    <button onClick={() => navigate('/pagename')}>
      Go To Page
    </button>
  );
}
Denni answered 23/1, 2023 at 10:5 Comment(0)
A
1

Simply use useNavigate from react router dom

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

const MYComponent = () => {
    const navigate = useNavigate();

    navigate("Xyz/MYRoutes");

 
}

export default MYComponent;

Use useNavigate feature like above in your code.

Awl answered 9/10, 2022 at 0:12 Comment(0)
M
1

You can tackle the option you want to let it do this thing.

<select>
 <option onClick={() => <Navigate to="/home" />}> Option 1 </option>
</select>

This you'll find in react-router-dom also you can use the hook, useNavigation()

const navigate = useNavigation();

navigate("/home") // use it onClick or anywhere.
Megara answered 20/7, 2023 at 17:0 Comment(0)
C
1
   import react from "react";

    // importing navigate from react-router-dom
    import {useNavigate} from "react-router-dom";
    
    function testNavigation() {
    const navigate = useNavigate();
    
    return (
    <>
    <button onClick={navigate("/")}> Test Navigate </button>

    </>
    )
    }

please note: before use nagivate path "/" in onClick make sure you already initial this path to your app.jsx file in your project which is provided react-router-dom in route.

Citation answered 4/9, 2023 at 11:38 Comment(1)
Thank you for your contribution! It would be very helpful if you could provide a brief explanation of the code you've posted and how it addresses the problem described in the question. This will make your answer more valuable for others who might come across this thread in the future, and will also help the original poster and other readers to understand the solution more clearly. Thanks in advance! If you need further knowledge check out: How To: Write a good answerHouseboy
B
0

Just using the browser api, independent of any library

const navigate = (to) => {
    window.history.pushState({}, ",", to);
  };

this does not cause full page refresh. you can still use the browser back button

Baxley answered 24/12, 2022 at 3:28 Comment(0)
K
0

There are several ways to navigate programmatically:

  1. Use web history API [https://developer.mozilla.org/en-US/docs/Web/API/History_API] eg: history("/route")
  2. Use callback function
  3. use push from connected-react-router eg: push({ pathname: "/route"})
Kerwinn answered 2/1 at 9:36 Comment(0)
X
0

In React Router, you can programmatically navigate to a different route using the useHistory hook (for functional components) or the withRouter HOC (for class components). Here's how you can do it using the useHistory hook:

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

const MyComponent = () => {
  const history = useHistory();

  const handleClick = () => {
    // Navigate to a different route programmatically
    history.push('/new-route');
  };

  return (
    <div>
      <button onClick={handleClick}>Go to New Route</button>
    </div>
  );
};
Xhosa answered 28/2 at 9:16 Comment(0)
F
0

In React Router v4 and later, the this.context approach for navigation has been replaced with hooks or higher-order components. To navigate programmatically without using mixins, you can use the useHistory hook or the withRouter higher-order component.

Here's how you can do it using the useHistory hook:

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

function MyComponent() {
  const history = useHistory();

  const handleDropdownChange = (event) => {
    const selectedValue = event.target.value;
    // Perform any logic based on the selected value
    // For example, navigate to a different route
    history.push(`/path/${selectedValue}`);
  };

  return (
    <div>
      <select onChange={handleDropdownChange}>
        <option value="option1">Option 1</option>
        <option value="option2">Option 2</option>
        <option value="option3">Option 3</option>
      </select>
    </div>
  );
}

export default MyComponent;

In this example, useHistory hook from react-router-dom is used to get the history object. Then, in the handleDropdownChange function, history.push is used to navigate to a different route based on the selected value from the dropdown.

If you prefer using a higher-order component approach, you can use withRouter:

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

class MyComponent extends React.Component {
  handleDropdownChange = (event) => {
    const { history } = this.props;
    const selectedValue = event.target.value;
    history.push(`/path/${selectedValue}`);
  };

  render() {
    return (
      <div>
        <select onChange={this.handleDropdownChange}>
          <option value="option1">Option 1</option>
          <option value="option2">Option 2</option>
          <option value="option3">Option 3</option>
        </select>
      </div>
    );
  }
}

export default withRouter(MyComponent);

In this example, withRouter is used to wrap MyComponent, which then injects the history object as a prop. The handleDropdownChange function uses history.push to navigate to a different route based on the selected value from the dropdown.

Florilegium answered 11/4 at 12:1 Comment(0)
L
-1

There are already a ton of answers which answer this question appropriately and accurately in the context of react router, but I'd like to take a moment to point out something that I didn't see mentioned in the other answers.

Kind of a stackoverflow trope to recommend doing something a different way than the original question asks, however in this case due to the age of the question I feel like the question would be stated differently in current time.

I'd recommend ditching react-router all together and just pushing to the native browser location, via window.location.href = [your url here], and checking path via regex (or exact) matching window.location.pathname against your intended path.

The simpler answer is usually the best one, and in this case, the use case for React Router is better served by the native Location object API.

Lamm answered 18/11, 2022 at 19:25 Comment(1)
Your answer is good enough but breaks the best practices when using the ReactJs library - You don't want to manipulate DOM directly for many reasons.Exculpate
R
-1

To perform navigation in React Router without using mixins, you can use the useHistory hook or the withRouter higher-order component (HOC). The this.context approach you mentioned is deprecated in React Router v6, so I'll provide examples using React Router v6.

  1. Using the useHistory hook:
    The useHistory hook allows you to access the history object, which provides navigation functionalities. Here's an example of how you can navigate programmatically using a dropdown selection:

    import { useHistory } from 'react-router-dom';
    
    function Dropdown() {
      const history = useHistory();
    
      const handleSelection = (path) => {
        history.push(path); // Navigate to the specified path
      };
    
      return (
        <select onChange={(e) => handleSelection(e.target.value)}>
          <option value="/">Home</option>
          <option value="/about">About</option>
          <option value="/contact">Contact</option>
        </select>
      );
    }
    

    In this example, the useHistory hook is imported from react-router-dom. Inside the Dropdown functional component, we access the history object via the useHistory hook.

    The handleSelection function is called whenever the dropdown selection changes. It uses history.push() to navigate to the specified path.

  2. Using withRouter HOC:
    If you prefer using classes or a functional component without hooks, you can use the withRouter higher-order component to inject the history object as a prop. Here's an example:

    import { withRouter } from 'react-router-dom'
    
    class Dropdown extends React.Component {
      handleSelection = (path) => {
        const { history } = this.props;
        history.push(path); // Navigate to the specified path
      };
    
      render() {
        return (
          <select onChange={(e) => this.handleSelection(e.target.value)}>
            <option value="/">Home</option>
            <option value="/about">About</option>
            <option value="/contact">Contact</option>
          </select>
        );
      }
    }
    
    export default withRouter(Dropdown);
    

    In this example, the withRouter HOC wraps the Dropdown component, injecting the history object as a prop. The handleSelection method uses this.props.history.push() to navigate to the specified path.

By using either the useHistory hook or the withRouter HOC, you can perform navigation programmatically in React Router without relying on mixins. Choose the method that best fits your project's requirements and coding style.

Russianize answered 3/8, 2023 at 12:49 Comment(0)
R
-2

layouts/BaseLayout.jsx

import { Outlet } from "react-router-dom";
import Navbar from "../components/Navbar";

const BaseLayout = () => {
    return(
        <div>
        <Navbar/>
        <Outlet/>
        </div>
    )
}

export default BaseLayout

routers/index.jsx

import { createBrowserRouter} from "react-router-dom";
import BaseLayout from "../layouts/BaseLayout";
import HomePage from "../views/HomePage";
import Menu from "../components/Menu"
import Detail from "../components/Detail";

const router = createBrowserRouter([
    {
        element: <BaseLayout/>,
        children:[
            {
                path: "/",
                element: <Menu />,
            },
            {
                path: '/:id',
                element: <Detail/>
            }
        ]

    },
])

export default router

stores/actionType.js

export const FETCH_DATA_FOODS = "food/setFood"

export const FETCH_DATA_FOODS_DETAILS = "food/setDetailFood"

stores/reducers/reducer.js

import { FETCH_DATA_FOODS, FETCH_DATA_FOODS_DETAILS } from "../actionType";

const initialState = {
    foods:[],
    detailFood:{}
};

const foodReducer = (state = initialState, action) => {
    switch(action.type){
        case FETCH_DATA_FOODS:
            return{
                ...state,
                foods: action.payload
            }
        case FETCH_DATA_FOODS_DETAILS:
            return{
                ...state,
                detailFood: action.payload
            }
        default:
            return state
    }
}

export default foodReducer

stores/actionCreator

import { FETCH_DATA_FOODS, FETCH_DATA_FOODS_DETAILS } from "./actionType";

// import { FETCH_DATA_FOODS } from "../actionType";
export const actionFoodSetFoods = (payload) => {
  return {
    type: FETCH_DATA_FOODS,
    payload,
  };
};

export const actionDetailSetDetailFood = (payload) => {
  return {
    type: FETCH_DATA_FOODS_DETAILS,
    payload,
  };
};

export const fetchDataFoods = () => {
  return (dispatch, getState) => {
    fetch("https://maxxkafe.foxhub.space/users")
      .then((response) => {
        if (!response.ok) {
          throw new Error("notOk");
        }
        return response.json();
      })
      .then((data) => {
        // dispatcher({
        //     type: "food/setFood",
        //     payload: data
        // })

        dispatch(actionFoodSetFoods(data));
      });
  };
};

export const fetchDetailDataFood = (id) => {
  return (dispatch, getState) => {
    console.log(id);
    fetch(`https://maxxkafe.foxhub.space/users/${id}`)
      .then((response) => {
        if (!response.ok) {
          throw new Error("gaOkNich");
        }
        console.log(response, ",,,,,,,,");
        return response.json();
      })
      .then((data) => {
        dispatch(actionDetailSetDetailFood(data));
      });
  };
};

stores/index.js

import { legacy_createStore as createStore, combineReducers, applyMiddleware } from 'redux'
import foodReducer from './reducers/foodReducer'
import thunk from "redux-thunk"

const rootReducer = combineReducers({
    foods: foodReducer
});

const store = createStore(rootReducer, applyMiddleware(thunk));

export default store

app.js

import { RouterProvider } from "react-router-dom";
import router from "./routers";
import { Provider } from "react-redux";
import store from "./stores";

const App = () => {
  return (
    <Provider store={store}>
      <RouterProvider router={router} />
    </Provider>
  );
};

export default App;

components/category.jsx

import { useEffect, useState } from "react";
import { useSelector, useDispatch } from "react-redux";
import { Link } from "react-router-dom";
import { fetchDataCategories } from "../stores/actionCreate";
import RowCategory from "../views/rowTableCategory";

const Category = () => {
  // const [categories, setCategories] = useState([])
  const { categories } = useSelector((state) => state.categories);
  const dispatcher = useDispatch();
  useEffect(() => {
    // fetch("http://localhost:3003/categories")
    // .then((response) => {
    //     if(!response.ok){
    //         throw new Error ("gaOkNich")
    //     }
    //     return response.json()
    // })
    // .then((data) => {
    //     setCategories(data)
    // })
    dispatcher(fetchDataCategories());
  }, []);
  return (
    <section className="mt-12">
      <div className="flex mr-20 mb-4">
        <Link to={'/add-Form'} className="flex ml-auto text-white bg-red-500 border-0 py-2 px-6 focus:outline-none hover:bg-red-600 rounded">
          Create Category
        </Link>
      </div>
      <div className="overflow-hidden rounded-lg border border-gray-200 shadow-md m-5">
        <table className="w-full border-collapse bg-white text-left text-sm text-gray-500">
          <thead className="bg-gray-50">
            <tr>
              <th scope="col" className="px-6 py-4 font-medium text-gray-900">
                Name
              </th>
              <th scope="col" className="px-6 py-4 font-medium text-gray-900">
                Created At
              </th>
              <th scope="col" className="px-6 py-4 font-medium text-gray-900">
                Updated At
              </th>
              <th
                scope="col"
                className="px-6 py-4 font-medium text-gray-900"
              ></th>
            </tr>
          </thead>
          <tbody className="divide-y divide-gray-100 border-t border-gray-100">
            {categories.map((el) => {
              return <RowCategory key={el.id} el={el} />;
            })}
          </tbody>
        </table>
      </div>
    </section>
  );
};

export default Category;

components/login.jsx

import { useState } from "react";
import { useNavigate } from "react-router-dom";
import { useDispatch } from "react-redux";
import { fetchDataFoods, login } from "../stores/actionCreate";

const Login = () => {
  const input = {
    email: "",
    password: "",
  };
  const [values, setValues] = useState(input);
  // const [password, setPassword] = useState('')
  // const {admin} = useSelector((state) => state.admin)

  const dispatcher = useDispatch();
  const movePage = useNavigate();

  const handleChange = (event) => {
    const { name, value } = event.target;
    setValues({
      ...values,
      [name]: value,
    });
    console.log(value);
  };

  const handleLogin = async (event) => {
    event.preventDefault();
    try {
      await dispatcher(login(values));
      await dispatcher(fetchDataFoods());
      movePage("/home");
    } catch (error) {
      console.log(error);
    }
  };

  return (
    <section className="font-mono bg-white-400 mt-[10rem]">
      <div className="container mx-auto">
        <div className="flex justify-center px-6 my-12">
          <div className="w-full xl:w-3/4 lg:w-11/12 flex justify-center">
            <div className="w-full lg:w-7/12 bg-white p-5 rounded-lg lg:rounded-l-none">
              <h3 className="pt-4 text-2xl text-center">Login Your Account!</h3>
              <form
                className="px-8 pt-6 pb-8 mb-4 bg-white rounded"
                onSubmit={handleLogin}
              >
                <div className="mb-4">
                  <label
                    className="block mb-2 text-sm font-bold text-gray-700"
                    htmlFor="email"
                  >
                    Email
                  </label>
                  <input
                    className="w-full px-3 py-2 mb-3 text-sm leading-tight text-gray-700 border rounded shadow appearance-none focus:outline-none focus:shadow-outline"
                    id="email"
                    type="email"
                    name="email"
                    placeholder="Email"
                    // onChange={(event) => setValues({email: event.target.value})}
                    onChange={handleChange}
                    value={values.email.email}
                  />
                </div>

                <div className="mb-4 md:flex md:justify-between">
                  <div className="mb-4 md:mr-2 md:mb-0">
                    <label
                      className="block mb-2 text-sm font-bold text-gray-700"
                      htmlFor="password"
                    >
                      Password
                    </label>
                    <input
                      className="w-full px-3 py-2 mb-3 text-sm leading-tight text-gray-700 border  rounded shadow appearance-none focus:outline-none focus:shadow-outline"
                      id="password"
                      type="password"
                      name="password"
                      placeholder="Password"
                      onChange={handleChange}
                      value={values.password}
                      // onChange={(event) => setValues({password: event.target.value})}
                    />
                  </div>
                </div>
                <div className="mb-4 md:flex md:justify-between"></div>
                <div className="mb-6 text-center">
                  <button
                    className="w-full px-4 py-2 font-bold text-white bg-blue-500 rounded-full hover:bg-blue-700 focus:outline-none focus:shadow-outline"
                    type="submit"
                  >
                    Login
                  </button>
                </div>
              </form>
            </div>
          </div>
        </div>
      </div>
    </section>
  );
};
export default Login;
Rover answered 23/1, 2023 at 12:33 Comment(1)
a lot of code not related to the answer to the question... you could at least comment what you're trying to demonstrate hereCystocarp
H
-5

Simply just use :

this.props.history.push('/where/to/go');
Herbal answered 21/9, 2017 at 7:26 Comment(1)
This answer is not clear and useful. I think everything have been answered above clearly and explained in every version of React and React Router. Please add more information if you think your answer is useful and better than them. Best regards Arash YazdaniIsidore

© 2022 - 2024 — McMap. All rights reserved.