使用react路由器以编程方式导航

时间:2015-06-26 17:38:52

标签: reactjs react-router

使用react-router我可以使用Link元素创建由反应路由器本地处理的链接。

我在内部看到它调用this.context.transitionTo(...)

我想进行导航,但不是从链接中进行导航,例如下拉选项。我怎么能在代码中这样做?什么是this.context

我看到了Navigation mixin,但我可以不用mixin吗?

37 个答案:

答案 0 :(得分:941)

  

React Router v4

使用React Router的v4,您可以采用三种方法在组件内进行编程路由。

  1. 使用withRouter高阶组件。
  2. 使用合成并渲染<Route>
  3. 使用context
  4. React Router主要是history库的包装器。 history通过浏览器和哈希历史记录处理与浏览器window.history的交互。它还提供了一个内存历史记录,对于没有全局历史记录的环境非常有用。这在移动应用程序开发(react-native)和使用Node的单元测试中特别有用。

    history个实例有两种导航方法:pushreplace。如果您将history视为一系列已访问过的位置,push将向阵列添加新位置,replace将使用新位置替换阵列中的当前位置。通常,您需要在导航时使用push方法。

    在早期版本的React Router中,您必须创建自己的history实例,但在第4版中,<BrowserRouter><HashRouter><MemoryRouter>组件将创建一个浏览器,哈希和内存实例。 React Router通过history对象下的上下文使与您的路由器关联的router实例的属性和方法可用。

    1。使用withRouter高阶组件

    withRouter高阶组件将history对象作为组件的支柱注入。这样,您就可以访问pushreplace方法,而无需处理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。使用合成并渲染<Route>

    <Route>组件不仅适用于匹配的位置。您可以渲染无路径路径,它将始终与当前位置匹配<Route>组件传递与withRouter相同的道具,因此您可以通过history道具访问history方法。

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

    3。使用上下文*

    但你可能不应该

    最后一个选项是您只有在使用React的context模型时才能使用的选项。虽然上下文是一种选择,但应该强调上下文是一个不稳定的API,React在其文档中有一个Why Not To Use Context部分。所以使用风险自负!

    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和2是最简单的选择,所以对于大多数用例来说,它们是你最好的选择。

答案 1 :(得分:784)

  

React-Router 4.0.0 + 回答

在4.0及以上版本中,使用历史记录作为组件的支柱。

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

注意:如果您的组件未由<Route>呈现,则不存在this.props.history。您应该使用<Route path="..." component={YourComponent}/>在YourComponent

中拥有this.props.history
  

React-Router 3.0.0 + 回答

在3.0及以上版本中,使用路由器作为组件的支柱。

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

React-Router 2.4.0 + 回答

在2.4及以上版本中,使用更高阶的组件将路由器作为组件的支柱。

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 + 回答

此版本向后兼容1.x,因此无需升级指南。只是通过这些例子就足够了。

也就是说,如果您想切换到新模式,那么您可以使用

访问路由器内部的browserHistory模块

import { browserHistory } from 'react-router'

现在您可以访问您的浏览器历史记录,因此您可以执行推送,替换等操作...例如:

browserHistory.push('/some/path')

进一步阅读: HistoriesNavigation

  

React-Router 1.x.x 答案

我不会进入升级细节。您可以在Upgrade Guide

中了解相关信息

这里问题的主要变化是从导航mixin到History的变化。现在它使用浏览器历史记录API来更改路线,因此我们将从现在开始使用pushState()

这是一个使用Mixin的例子:

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

请注意,此History来自rackt/history项目。不是来自React-Router本身。

如果您因某些原因不想使用Mixin(可能是因为ES6类),那么您可以从this.props.history访问路由器获得的历史记录。它只能由路由器呈现的组件访问。因此,如果要在任何子组件中使用它,则需要通过props作为属性传递它。

您可以在1.0.x documentation

了解有关新版本的更多信息

这是a help page specifically about navigating outside your component

建议抓取引用history = createHistory()并在其上调用replaceState

  

React-Router 0.13.x 答案

我遇到了同样的问题,只能通过react-router附带的Navigation mixin找到解决方案。

以下是我的表现

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>);
  }
});

我无需访问transitionTo()

即可致电.context

或者您可以尝试花哨的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
};
  

<强>阵营-路由器-终极版

     

注意:如果您正在使用Redux,则会有另一个名为的项目   给你的React-Router-Redux   ReactRouter的redux绑定,使用的方法与之相同   React-Redux确实

React-Router-Redux有一些可用的方法,允许从内部动作创建者进行简单的导航。这些对于在React Native中具有现有体系结构的人来说特别有用,并且他们希望在React Web中使用相同的模式,只需最少的样板开销。

探索以下方法:

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

以下是使用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>

答案 2 :(得分:485)

  

React-Router v2

对于最新版本(v2.0.0-rc5),推荐的导航方法是直接推送历史单例。您可以在Navigating outside of Components doc中看到这一点。

相关摘录:

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

如果使用较新的react-router API,则需要在组件内部使用来自history的{​​{1}}:

this.props

它还提供this.props.history.push('/some/path'); ,但每个已记录的警告都会弃用。

如果使用pushState,它会提供react-router-redux功能,您可以这样发送:

push

但是,这可能仅用于更改网址,而不是实际导航到网页。

答案 3 :(得分:46)

以下是使用react-router v2.0.0 ES6执行此操作的方法。 react-router已离开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
}

答案 4 :(得分:32)

  

React-Router 4.x答案:

在我的结尾,我喜欢有一个历史对象,我可以携带甚至外部组件。我喜欢做的是拥有一个我按需导入的单个history.js文件,并且只是操作它。

您只需将BrowserRouter更改为路由器,然后指定历史记录道具。除了您拥有自己可以根据需要操作的历史对象外,这对您没有任何改变。

您需要安装react-router import createBrowserHistory from 'history/createBrowserHistory' export default createBrowserHistory() 使用的库。

示例用法,ES6表示法:

<强> history.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>;
    }
}

<强> BasicComponent.js

Route
  

编辑2018年4月16日:

如果您必须从实际从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>; } } 组件呈现的组件导航,您还可以从道具访问历史记录,如:

<强> BasicComponent.js

SharedVariables

答案 5 :(得分:31)

对于这个,谁不控制服务器端,因此使用散列路由器v2:

history放入单独的文件中(例如app_history.js ES6):

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

export default appHistory;

并在任何地方使用它!

您对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"]'));

您在任何组件(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()
  }
})

答案 6 :(得分:24)

  

警告:此答案仅涵盖1.0之前的ReactRouter版本

     

我将在1.0.0-rc1用例后更新此答案!

你可以在没有mixins的情况下做到这一点。

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>);
  }
});

带有上下文的问题是,除非您在类上定义contextTypes,否则无法访问它。

至于什么是上下文,它是一个对象,比如props,从父节点传递给子节点,但是它是隐式传递的,不必每次都重新声明道具。见https://www.tildedave.com/2014/11/15/introduction-to-contexts-in-react-js.html

答案 7 :(得分:24)

  

React Router V4

TL:博士;

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

简单且声明性的答案是,您需要将<Redirect to={URL} push={boolean} />setState()结合使用

  

push:boolean - 当为true时,重定向会将新条目推送到历史记录而不是替换当前的条目。

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>
    )
  }
}

完整示例here。 阅读更多here

PS。该示例使用ES7+ Property Initializers初始化状态。如果您有兴趣,请查看here

答案 8 :(得分:20)

在一些正常工作之前,我尝试过至少10种方法!

@Felipe Skinner的withRouter答案对我来说有点压倒性的,我不确定我是否想制作新的“ExportedWithRouter”类名。

这是最简单,最干净的方法,大约当前的React-Router 3.0.0和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);

或者,如果它不是您的默认类,则导出如下:

withRouter(Example);
export { Example };

请注意,在3.x.x中,<Link>组件本身正在使用router.push,因此您可以将任何传递给<Link to=标记的内容传递给它,例如:

   this.props.router.push({pathname: '/some/path', query: {key1: 'val1', key2: 'val2'})'

答案 9 :(得分:18)

要以编程方式进行导航,您需要将新的历史记录推送到component中的 props.history ,这样的内容就可以了为你工作:

//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;

答案 10 :(得分:16)

对于ES6 + React组件,以下解决方案适用于我。

我跟着Felippe skinner,但添加了一个端到端的解决方案来帮助像我这样的初学者。

以下是我使用的版本:

  

“react-router”:“^ 2.7.0”

     

“反应”:“^ 15.3.1”

下面是我的反应组件,我使用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;

以下是我的路由器的配置:

 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'));

答案 11 :(得分:16)

请找到以下工作代码: 如this article中所述,这是使用react Router导航的一种非常简单的方法:

class Register extends React.Component {
  state = {
    toDashboard: false,
  }
  handleSubmit = (user) => {
    saveUser(user)
      .then(() => this.setState(() => ({
        toDashboard: true
      })))
  }
  render() {
    if (this.state.toDashboard === true) {
      return <Redirect to='/dashboard' />
    }

    return (
      <div>
        <h1>Register</h1>
        <Form onSubmit={this.handleSubmit} />
      </div>
    )
  }
}

<< strong>重定向 />是

  

可组合✅声明性✅用户事件->状态更改->重新呈现✅

React Router正在渲染注册组件,我们的代码可能如下所示

class Register extends React.Component {
  handleSubmit = (user) => {
    saveUser(user).then(() =>
      this.props.history.push('/dashboard')
    ))
  }
  render() {
    return (
      <div>
        <h1>Register</h1>
        <Form onSubmit={this.handleSubmit} />
      </div>
    )
  }
}

通过添加withRouter,看起来像这样

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

class Register extends React.Component {
  handleSubmit = (user) => {
    saveUser(user).then(() =>
      this.props.history.push('/dashboard')
    ))
  }
  render() {
    return (
      <div>
        <h1>Register</h1>
        <Form onSubmit={this.handleSubmit} />
      </div>
    )
  }
}

export default withRouter(Register)

有两种方法可以使用React Router以编程方式进行导航-和history.push。尽管我会尽量支持重定向,但您使用哪种主要取决于您和您的特定用例。

答案 12 :(得分:15)

可能不是最好的方法,但是...使用react-router v4,以下的Typescript可以给出一些想法。

在下面的渲染组件中,例如可以访问LoginPagerouter对象,只需致电router.transitionTo('/homepage')即可导航。

导航代码来自https://react-router.now.sh/Match

"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')
);

答案 13 :(得分:14)

  

React-Router v4 ES6

您可以使用withRouterthis.props.history.push

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

class Home extends Component {

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

export default withRouter(Home);

答案 14 :(得分:12)

要将withRouter与基于类的组件一起使用,请尝试以下操作。 不要忘记更改导出语句以使用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);

答案 15 :(得分:9)

基于之前的答案
来自JoséAntonioPostigo和Ben Wheeler 新奇?将用打字稿写成 和装饰者的使用 或静态属性/字段

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>
        )
    }
}

使用今天安装的任何npm。 “react-router”:“^ 3.0.0”和
“@ types / react-router”:“^ 2.0.41”

答案 16 :(得分:9)

即将推出React-Router v4,现在有了一种新方法。

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是一个展示how to use/update react-router的示例应用,它包含了导航应用的示例功能测试。

答案 17 :(得分:8)

在反应路由器v4中。我按照以下两种方式以编程方式进行路由。

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

第二名

  

替换历史记录堆栈中的当前条目

要获取道具的历史记录,您可能需要用

包装组件
  

withRouter https://reacttraining.com/react-router/core/api/withRouter

答案 18 :(得分:7)

使用当前的React版本(15.3),Attachment为我工作,但它显示以下警告:

  

browser.js:49警告:[react-router] this.props.history.push('/location');和   不推荐使用props.history。请使用context.history

我使用context.router解决了这个问题:

context.router

答案 19 :(得分:7)

如果您使用哈希值或浏览器历史记录,则可以执行

hashHistory.push('/login');
browserHistory.push('/login');

答案 20 :(得分:5)

React-Router V4

如果您使用的是版本4,那么您可以使用我的库(无耻插件),只需发送一个动作,一切正常!

collect_list

https://www.npmjs.com/package/trippler

答案 21 :(得分:5)

更新:带有钩子的React Router v6

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

要浏览浏览器的历史记录,

navigate(-1); ---> Go back
navigate(1);  ---> Go forward
navigate(-2); ---> Move two steps backward.

答案 22 :(得分:5)

在react-router v4上实现此功能时遇到问题的人。

这是从redux动作导航到react应用的可行解决方案。

history.js

import createHistory from 'history/createBrowserHistory'

export default createHistory()

App.js / Route.jsx

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

another_file.js或redux文件

import history from './history' 

history.push('/test') // this should change the url and re-render Test component

全部感谢此评论: ReactTraining issues comment

答案 23 :(得分:4)

如果碰巧将RR4 w / redux与react-router-redux配对,那么使用react-router-redux中的路由操作创建器也是一种选择。

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)

如果使用redux thunk / saga来管理异步流,请在redux动作中导入上面的动作创建者,并使用mapDispatchToProps钩子反应组件可能会更好。

答案 24 :(得分:3)

在撰写本文时,正确的答案是给我的

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

但您需要将PropTypes添加到组件

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

不要忘记导入PropTypes

import PropTypes from 'prop-types';

答案 25 :(得分:3)

也许不是最好的解决方案,但它可以完成工作:

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>
);

基本上,绑定到一个动作的逻辑(在这种情况下是删除后)将最终调用重定向的触发器。这不是理想的,因为您将向标记添加DOM节点“触发器”,以便您可以在需要时方便地调用它。此外,您将直接与DOM进行交互,在React组件中可能不需要它。

但是,通常不需要这种类型的重定向。因此,组件标记中的一个或两个额外的隐藏链接不会对此造成太大影响,特别是如果您为它们提供有意义的名称。

答案 26 :(得分:3)

您还可以在无状态组件中使用useHistory钩子。文档中的示例。

import { useHistory } from "react-router"

function HomeButton() {
  const history = useHistory()

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

注意:挂钩是在react-router@5.1.0中添加的,并且需要react@>=16.8

答案 27 :(得分:3)

尝试使用hookrouter,“ react-router的现代替代品”

https://www.npmjs.com/package/hookrouter

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

回答关于通过选择框链接的OP问题,您可以这样做:

navigate('/about');

***更新后的答案***

我认为hook-router是一个很好的入门工具包,可以帮助我学习路由,但是此后由于其历史记录和查询参数处理而更新为react-router。

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


const Component = (props) => {
    const history = useHistory();
    
    // Programmatically navigate
    history.push(newUrlString);
}

将您要导航到location.history的位置。

答案 28 :(得分:3)

以编程方式在基于类的组件中导航。

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}/>
        }
        .....
        .....
    }
}

希望,有帮助。

答案 29 :(得分:2)

这对我有用,不需要特殊导入:

<input 
  type="button" 
  name="back" 
  id="back" 
  class="btn btn-primary" 
  value="Back" 
  onClick={() => { this.props.history.goBack() }} 
/>

答案 30 :(得分:0)

  

对于React Router v4 +

假设您不需要在初始渲染本身期间进行导航(可以使用<Redirect>组件),这就是我们在应用程序中所做的。

定义一个空路由,该路由返回null,这将使您能够访问历史对象。您需要在定义了Router的顶层执行此操作。

现在您可以在history上完成所有操作,例如history.push()history.replace()history.go(-1)等!

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>
  );
}

答案 31 :(得分:0)

因此,在我的回答中,有3种不同的方式以编程方式重定向到路由。已经提供了一些解决方案,但以下解决方案仅针对 功能组件 以及其他演示应用程序。

使用以下版本:

  

反应: 16.12.0

     

反应区域: 16.12.0

     

反应路由器: 5.1.2

     

react-router-dom: 5.1.2

     

打字稿: 3.7.2

配置:

因此,首先解决方案是使用HashRouter,其配置如下:

<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>

documentation关于<HashRouter>

  

使用URL的哈希部分(即<Router>)使您的UI与URL保持同步的window.location.hash

解决方案:

  1. 使用<Redirect>通过useState进行推送:

使用功能组件(我的存储库中的RedirectPushAction组件),我们可以使用useState来处理重定向。棘手的部分是,一旦发生重定向,我们需要将redirect状态设置回false。通过将setTimeOut延迟使用0,我们将等到React将Redirect提交给DOM,然后再取回按钮以便下次使用。

请在下面找到我的示例:

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

        // in order wait until commiting 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>
</>

摘自<Redirect>文档:

  

渲染<Redirect>将导航到新位置。新位置将覆盖历史记录堆栈中的当前位置,就像服务器端重定向(HTTP 3xx)一样。

  1. 使用useHistory钩子:

在我的解决方案中,有一个名为UseHistoryAction的组件,它表示以下内容:

let history = useHistory();

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

通过useHistory钩子,我们可以访问历史记录对象,这有助于我们以编程方式导航或更改路线。

  1. 使用withRouter,从history获取props

创建了一个名为WithRouterAction的组件,显示如下:

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

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

export default withRouter(WithRouterAction);

withRouter文档中阅读:

  

您可以通过history高阶组件访问<Route>对象的属性和最接近的withRouter匹配项。每当渲染时,withRouter会将更新后的matchlocationhistory道具传递给包装的组件。

演示:

为了更好地表示,我使用以下示例构建了一个GitHub存储库,请在下面找到它:

https://github.com/norbitrial/react-router-programmatically-redirect-examples

我希望这会有所帮助!

答案 32 :(得分:0)

如果您使用的是较新版本的react,最好使用“ useHistory”挂钩

答案 33 :(得分:-1)

反应路由器域:5.1.2

  • 此站点有3个页面,所有页面均在浏览器中动态呈现。

  • 尽管该页面从未刷新,但请注意React Router如何 在浏览网站时使URL保持最新。这个 保留浏览器历史记录,确保背面 按钮和书签正常工作

  • 开关会查看所有子项       元素并渲染第一个路径       与当前网址匹配。随时使用       您有多条路线,但您只想一条       一次渲染它们

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>
  );
}```

答案 34 :(得分:-2)

简单的反应路由:

链接到我的代码沙箱。 它还有其他一些简单的react-redux程序。

答案 35 :(得分:-2)

只需使用this.props.history.push('/where/to/go');

即可

答案 36 :(得分:-2)

我们可以从 index.js 开始:

import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
import { BrowserRouter } from "react-router-dom";

ReactDOM.render(
  <BrowserRouter>
    <App />
  </BrowserRouter>,
  document.getElementById("root")
);

reportWebVitals();
<块引用>

我一直在使用这个包:

"react-dom": "^17.0.1",
    "react-router-dom": "^5.2.0",

文件 app.js

import { Switch, Route } from "react-router-dom";

class App extends React.Component {
  constructor() {
    super();

    this.state = {
      currentUser: null,
    };
  }

  //important
  unsubscribeFromAuth = null;

  componetDidMount() {
    this.unsubscribeFromAuth = auth.onAuthStateChanged((user) => {
      this.setState({ currentUser: user });
    });
  }

  componentWillUnmount() {
    this.unsubscribeFromAuth();
  }

  render() {
    return (
      <div>
        <Header currentUser />
        <Switch>
          <Route exact path="/" component={HomePage} />
          <Route path="/shop" component={ShopPage} />
          <Route path="/signin" component={SignInSignUpage} />
        </Switch>
      </div>
    );
  }
}

export default App;

exact path="/" 有助于获取准确路径,这就是我们可以轻松呈现您的页面的原因。