Làm thế nào để chuyển hướng đến một tuyến đường khác với bộ định tuyến phản ứng?


95

Tôi đang cố gắng thực hiện MỘT ĐƠN GIẢN bằng cách sử dụng bộ định tuyến phản ứng ( phiên bản ^ 1.0.3 ) để chuyển hướng sang chế độ xem khác và tôi chỉ cảm thấy mệt mỏi.

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;

tất cả những gì tôi cần là gửi quyền sử dụng đến '/ login' và thế là xong.

Tôi có thể làm gì ?

lỗi trong bảng điều khiển:

Uncaught ReferenceError: PropTypes không được xác định

nộp hồ sơ với các tuyến đường của tôi

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

Chào! Bạn có thể đăng các routesđịnh nghĩa của mình , và nếu có lý do bạn không sử dụng Linkcomponent? Ngoài ra, hãy đề cập đến những lỗi bạn mắc phải.
aarosil

Thay vì nút <Link to="/login">Log In</Link>,?
aarosil

Ngoài ra, bạn đang sử dụng phiên bản react-router nào? Mã để chuyển hướng theo thủ tục đã thay đổi giữa các phiên bản chính.
mjhm

4
Đối với Uncaught ReferenceError, bạn đang gọi là PropTypes, nhưng bạn không nhập khẩu đó, bạn cần nhập PropTypes như bản thân hoặc sử dụngReact.PropTypes
aarosil

1
Điểm tốt @JoshDavidMiller Tuy nhiên tôi sẽ không được ngạc nhiên react-routerthay đổi api trong vòng 5 phút .. haha đùa, nhưng chỉ một phần
aarosil

Câu trả lời:


33

Đối với câu trả lời đơn giản, bạn có thể sử dụng Linkthành phần từ react-router, thay vì button. Có nhiều cách để thay đổi lộ trình trong JS, nhưng có vẻ như bạn không cần điều đó ở đây.

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

Để làm điều đó theo chương trình trong 1.0.x, bạn làm như thế này, bên trong hàm clickHandler của bạn:

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

Lấy từ tài liệu nâng cấp tại đây

Bạn nên this.historyđặt trên thành phần xử lý tuyến đường của mình bằng react-router. Nếu nó là thành phần con bên dưới được đề cập trong routesđịnh nghĩa, bạn có thể cần chuyển nó xuống thêm


2
đây là giải pháp tuyệt vời, nhưng lý do tại sao tôi không sử dụng nó, là vì trước tiên tôi cần thực hiện như một loại xác thực, vì vậy tôi cần đặt điều này vào một hàm, như: if (true) { // redirect to login}vì vậy đó là lý do tại sao tôi đặt nó vào onClick chức năng
Phản ứng

5
Bạn cũng có thể làm điều đó trong JSX: {validation && <Link to="/login" />Click to login</Link>}. Nếu xác nhận sai, không có gì sẽ hiển thị.
aarosil

Tôi biết ý bạn là gì, nhưng tôi cần nút ở đó, nếu xác thực là đúng thì hãy chuyển hướng, nếu không sẽ xuất hiện thông báo lỗi.
Phản ứng

@TheUnnamed tôi cập nhật câu trả lời cho thấy làm thế nào làm điều đó trong JS
aarosil

1
> Uncaught TypeError: Không thể đọc thuộc tính 'pushState' của undefined
phản hồi

94

1) react-router> V5 useHistoryhook:

Nếu bạn có React >= 16.8và các thành phần chức năng, bạn có thể sử dụng useHistory hook từ 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;

2) react-router> V4 withRouterHOC:

Như @ambar đã đề cập trong các nhận xét, React-router đã thay đổi cơ sở mã của họ kể từ phiên bản V4. Đây là các tài liệu - chính thức , 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 với browserHistory

Bạn có thể đạt được chức năng này bằng cách sử dụng bộ định tuyến phản ứng BrowserHistory. Mã bên dưới:

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

Nếu bạn đã kết nối thành phần của mình với redux và đã định cấu hình bộ định tuyến kết nối-phản ứng, tất cả những gì bạn phải làm là this.props.history.push("/new/url");, bạn không cần withRouterHOC để đưa historyvào các đạo cụ thành phần.

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

3
Có vẻ như 'browserHistory' không còn là một phần của react-router nữa.
ambar

BrowserRouter không có chức năng push
johnnyodonnell

@ambar @johnnyodonnell react-router-domhiện
toinetoine

Đây là câu trả lời tốt nhất. Bạn nên đánh dấu cái này là cái đúng.
Solomon Bush

23

Làm thế nào để chuyển hướng đến một tuyến đường khác với bộ định tuyến phản ứng?

Ví dụ: khi người dùng nhấp vào, một <Link to="/" />Click to route</Link>bộ định tuyến phản ứng liên kết sẽ tìm kiếm /và bạn có thể sử dụng Redirect tovà gửi người dùng đến một nơi khác như lộ trình đăng nhập.

Từ các tài liệu cho ReactRouterTraining :

Hiển thị một <Redirect>sẽ điều hướng đến một vị trí mới. Vị trí mới sẽ ghi đè vị trí hiện tại trong ngăn xếp lịch sử, giống như chuyển hướng phía máy chủ (HTTP 3xx).

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

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

to: string, URL để chuyển hướng đến.

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

to: object, Vị trí để chuyển hướng đến.

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

Giải pháp được cung cấp sẽ tạo ra một lỗi <Redirect> elements are for router configuration only and should not be rendered.
t1gor 27/03/18

10

Giải pháp dễ nhất cho web!

Đến năm 2020
xác nhận làm việc với:

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

Sử dụng useHistory()móc!

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

Tuyệt vời, đang tìm kiếm cách hấp dẫn để làm điều đó! Mặc dù IDE của tôi có cảnh báo "Không thể giải quyết biểu tượng ...", nó vẫn hoạt động!
Rafael Moni

7

Với react-router v2.8.1 (có thể là các phiên bản 2.xx khác, nhưng tôi chưa thử nghiệm nó), bạn có thể sử dụng triển khai này để thực hiện chuyển hướng Router.

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

đôi khi: this.context.router.history.push ('/ some-path');
象 嘉 道

4

Giải pháp đơn giản nhất là:

import { Redirect } from 'react-router';

<Redirect to='/componentURL' />

Nhưng tôi gặp lỗi: Bất biến không thành công: Bạn không nên sử dụng <Redirect> bên ngoài <Router>
Prateek Gupta

Bạn đã thử quấn chưa?
Jackkobec
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.