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

新手上路,请多包涵

我正在尝试使用 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;

我需要的只是将使用发送到’/login’,就是这样。

我能做些什么 ?

控制台中的错误:

未捕获的 ReferenceError:未定义 PropTypes

用我的路线归档

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

原文由 Reacting 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.1k
2 个回答

对于简单的答案,您可以使用 react-router 中的 Link 组件,而不是 button 。有一些方法可以改变 JS 中的路线,但似乎你在这里不需要。

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

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

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

取自升级文档 here

您应该通过 react-routerthis.history 放置在您的路由处理程序组件上。如果它是 routes 定义中提到的子组件,您可能需要进一步传递它

原文由 aarosil 发布,翻译遵循 CC BY-SA 4.0 许可协议

1)反应路由器> V6 useNavigate 挂钩:

如果您有 React >= 16.8 和功能组件,您可以使用 useNavigate 来自 react-router 的钩子

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

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

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

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

export default YourComponent;

2) 反应路由器 > V5 useHistory 挂钩:

如果您有 react-router v5 和功能组件,您可以使用 useHistory 来自 react-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;

3) 反应路由器 > V4 withRouter HOC:

正如 @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);

4) React-router < V4 with browserHistory

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

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

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

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

5) 终极 connected-react-router

如果你已经用 redux 连接了你的组件,并且配置了 connected-react-router 你所要做的就是 this.props.history.push("/new/url"); 即,你不需要 withRouter HOC 注入 history 组件道具。

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

原文由 Noushad 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题