Javascript 如何使用 react-router 重定向到另一条路由?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/34735580/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 16:48:02  来源:igfitidea点击:

How to do a redirect to another route with react-router?

javascriptreactjs

提问by Reacting

I am trying to do A SIMPLE using react-router ( version ^1.0.3) to redirect to another view and I am just getting tired.

我正在尝试使用 react-router(版本 ^1.0.3)做一个简单的重定向到另一个视图,我只是累了。

import React from 'react';
import {Router, Route, Link, RouteHandler} from 'react-router';


class HomeSection extends React.Component {

  static contextTypes = {
    router: PropTypes.func.isRequired
  };

  constructor(props, context) {
    super(props, context);
  }

  handleClick = () => {
    console.log('HERE!', this.contextTypes);
    // this.context.location.transitionTo('login');
  };

  render() {
    return (
      <Grid>
        <Row className="text-center">          
          <Col md={12} xs={12}>
            <div className="input-group">
              <span className="input-group-btn">
                <button onClick={this.handleClick} type="button">
                </button>
              </span>
            </div>
          </Col>
        </Row>
      </Grid>
    );
  }
};

HomeSection.contextTypes = {
  location() {
    React.PropTypes.func.isRequired
  }
}

export default HomeSection;

all I need is to send the use to '/login' and that's it.

我所需要的只是将使用发送到“/登录”,就是这样。

What can I do ?

我能做什么 ?

errors in console:

控制台中的错误:

Uncaught ReferenceError: PropTypes is not defined

未捕获的 ReferenceError:未定义 PropTypes

file with my routes

包含我的路线的文件

// LIBRARY
/*eslint-disable no-unused-vars*/
import React from 'react';
/*eslint-enable no-unused-vars*/
import {Route, IndexRoute} from 'react-router';

// COMPONENT
import Application from './components/App/App';
import Contact from './components/ContactSection/Contact';
import HomeSection from './components/HomeSection/HomeSection';
import NotFoundSection from './components/NotFoundSection/NotFoundSection';
import TodoSection from './components/TodoSection/TodoSection';
import LoginForm from './components/LoginForm/LoginForm';
import SignupForm from './components/SignupForm/SignupForm';

export default (
    <Route component={Application} path='/'>
      <IndexRoute component={HomeSection} />
      <Route component={HomeSection} path='home' />
      <Route component={TodoSection} path='todo' />
      <Route component={Contact} path='contact' />
      <Route component={LoginForm} path='login' />
      <Route component={SignupForm} path='signup' />
      <Route component={NotFoundSection} path='*' />
    </Route>
);

采纳答案by aarosil

For the simple answer, you can use Linkcomponent from react-router, instead of button. There is ways to change the route in JS, but seems you don't need that here.

对于简单的答案,您可以使用Link组件 from react-router,而不是button。有多种方法可以更改 JS 中的路由,但您似乎不需要这里。

<span className="input-group-btn">
  <Link to="/login" />Click to login</Link>
</span>

To do it programmatically in 1.0.x, you do like this, inside your clickHandler function:

要在 1.0.x 中以编程方式执行此操作,您可以在 clickHandler 函数中执行以下操作:

this.history.pushState(null, 'login');

this.history.pushState(null, 'login');

Taken from upgrade doc here

取自此处的升级文档

You should have this.historyplaced on your route handler component by react-router. If it child component beneath that mentioned in routesdefinition, you may need pass that down further

您应该this.history通过react-router. 如果它是routes定义中提到的子组件,您可能需要进一步传递它

回答by Noushad

1) react-router > V5 useHistoryhook:

1)反应路由器> V5useHistory钩子:

If you have React >= 16.8and functional components you can use the useHistoryhook from react-router.

如果您有React >= 16.8功能组件,您可以使用useHistoryreact-router 中钩子

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

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

    const handleClick = () => {
        history.push("/path/to/push");
    }

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

export default YourComponent;

2) react-router > V4 withRouterHOC:

2)反应路由器> V4 withRouterHOC:

As @ambar mentioned in the comments, React-router has changed their code base since their V4. Here are the documentations - official, withRouter

正如@ambar 在评论中提到的,React-router 自 V4 以来已经改变了他们的代码库。这是文档 -官方的withRouter

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

class YourComponent extends Component {
    handleClick = () => {
        this.props.history.push("path/to/push");
    }

    render() {
        return (
            <div>
                <button onClick={this.handleClick} type="button">
            </div>
        );
    };
}

export default withRouter(YourComponent);

3) React-router < V4 with browserHistory

3) React-router < V4 with browserHistory

You can achieve this functionality using react-router BrowserHistory. Code below:

您可以使用 react-router 实现此功能BrowserHistory。代码如下:

import React, { Component } from 'react';
import { browserHistory } from 'react-router';

export default class YourComponent extends Component {
    handleClick = () => {
        browserHistory.push('/login');
    };

    render() {
        return (
            <div>
                <button onClick={this.handleClick} type="button">
            </div>
        );
    };
}

4) Redux connected-react-router

4) 还原 connected-react-router

If you have connected your component with redux, and have configured connected-react-routerall you have to do is this.props.history.push("/new/url");ie, you don't need withRouterHOC to inject historyto the component props.

如果你已经将你的组件与 redux 连接起来,并且已经配置了connected-react-router,你所要做的 this.props.history.push("/new/url");就是,你不需要withRouterHOC 来注入history组件 props。

// reducers.js
import { combineReducers } from 'redux';
import { connectRouter } from 'connected-react-router';

export default (history) => combineReducers({
    router: connectRouter(history),
    ... // rest of your reducers
});


// configureStore.js
import { createBrowserHistory } from 'history';
import { applyMiddleware, compose, createStore } from 'redux';
import { routerMiddleware } from 'connected-react-router';
import createRootReducer from './reducers';
...
export const history = createBrowserHistory();

export default function configureStore(preloadedState) {
    const store = createStore(
        createRootReducer(history), // root reducer with router state
        preloadedState,
        compose(
            applyMiddleware(
                routerMiddleware(history), // for dispatching history actions
                // ... other middlewares ...
            ),
        ),
    );

    return store;
}


// set up other redux requirements like for eg. in index.js
import { Provider } from 'react-redux';
import { Route, Switch } from 'react-router';
import { ConnectedRouter } from 'connected-react-router';
import configureStore, { history } from './configureStore';
...
const store = configureStore(/* provide initial state if any */)

ReactDOM.render(
    <Provider store={store}>
        <ConnectedRouter history={history}>
            <> { /* your usual react-router v4/v5 routing */ }
                <Switch>
                    <Route exact path="/yourPath" component={YourComponent} />
                </Switch>
            </>
        </ConnectedRouter>
    </Provider>,
    document.getElementById('root')
);


// YourComponent.js
import React, { Component } from 'react';
import { connect } from 'react-redux';
...

class YourComponent extends Component {
    handleClick = () => {
        this.props.history.push("path/to/push");
    }

    render() {
        return (
          <div>
            <button onClick={this.handleClick} type="button">
          </div>
        );
      }
    };

}

export default connect(mapStateToProps = {}, mapDispatchToProps = {})(YourComponent);

回答by jtlindsey

How to do a redirect to another route with react-router?

如何使用 react-router 重定向到另一条路由?

For example, when a user clicks a link <Link to="/" />Click to route</Link>react-router will look for /and you can use Redirect toand send the user somewhere else like the login route.

例如,当用户单击链接时,<Link to="/" />Click to route</Link>react-router 将查找/,您可以使用Redirect to并将用户发送到其他地方,例如登录路由。

From the docsfor ReactRouterTraining:

文档ReactRouterTraining

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.

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

import { Route, Redirect } from 'react-router'

<Route exact path="/" render={() => (
  loggedIn ? (
    <Redirect to="/dashboard"/>
  ) : (
    <PublicHomePage/>
  )
)}/>

to: string, The URL to redirect to.

to:字符串,要重定向到的 URL。

<Redirect to="/somewhere/else"/>

to: object, A location to redirect to.

to:对象,要重定向到的位置。

<Redirect to={{
  pathname: '/login',
  search: '?utm=your+face',
  state: { referrer: currentLocation }
}}/>

回答by Scott Plunkett

Easiestsolution for web!

最简单的网络解决方案!

Up to date 2020
confirmed working with:

截至 2020 年,
已确认与以下机构合作:

"react-router-dom": "^5.1.2"
"react": "^16.10.2"

Use the useHistory()hook!

使用useHistory()钩子!

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


export function HomeSection() {
  const history = useHistory();
  const goLogin = () => history.push('login');

  return (
    <Grid>
      <Row className="text-center">          
        <Col md={12} xs={12}>
          <div className="input-group">
            <span className="input-group-btn">
              <button onClick={goLogin} type="button" />
            </span>
          </div>
        </Col>
      </Row>
    </Grid>
  );
}

回答by Tom Van Rompaey

With react-router v2.8.1 (probably other 2.x.x versions as well, but I haven't tested it) you can use this implementation to do a Router redirect.

使用 react-router v2.8.1(也可能是其他 2.xx 版本,但我还没有测试过),您可以使用此实现来执行路由器重定向。

import { Router } from 'react-router';

export default class Foo extends Component {

  static get contextTypes() {
    return {
      router: React.PropTypes.object.isRequired,
    };
  }

  handleClick() {
    this.context.router.push('/some-path');
  }
}

回答by Hymankobec

The simplest solution is:

最简单的解决方案是:

import { Redirect } from 'react-router';

<Redirect to='/componentURL' />