Làm thế nào để đẩy vào Lịch sử trong React Router v4?


360

Trong phiên bản hiện tại của React Router (v3), tôi có thể chấp nhận phản hồi của máy chủ và sử dụng browserHistory.pushđể đi đến trang phản hồi thích hợp. Tuy nhiên, điều này không có sẵn trong v4 và tôi không chắc cách thích hợp để xử lý việc này là gì.

Trong ví dụ này, sử dụng Redux, các thành phần / ứng dụng-sản phẩm-form.js gọi this.props.addProduct(props)khi người dùng gửi biểu mẫu. Khi máy chủ trả về thành công, người dùng sẽ được đưa đến trang Giỏ hàng.

// actions/index.js
export function addProduct(props) {
  return dispatch =>
    axios.post(`${ROOT_URL}/cart`, props, config)
      .then(response => {
        dispatch({ type: types.AUTH_USER });
        localStorage.setItem('token', response.data.token);
        browserHistory.push('/cart'); // no longer in React Router V4
      });
}

Làm cách nào tôi có thể chuyển hướng đến trang Giỏ hàng từ chức năng cho React Router v4?


Chỉ cần thêm vào điều này từ giải pháp cuối cùng được cung cấp và từ các đề xuất trong các vấn đề của React Router trên GitHub, sử dụng contextđể vượt qua những gì bạn cần một cách thủ công là "không đi". Trừ khi tôi là một tác giả thư viện, không nên sử dụng nó. Trong thực tế, Facebook khuyến cáo chống lại nó.
Chris

@Chris bạn đã tìm ra giải pháp cho việc này chưa? Tôi cần đẩy đến một thành phần khác trong hành động, giống như bạn đã giải thích ở đây
Mr.G

@ Mr.G, đáng buồn là tôi không có. Lần cuối tôi đọc là nhóm Đào tạo React duy trì Bộ định tuyến React có sẵn gói redux. Tôi đã không có may mắn làm cho nó hoạt động, và họ đã không đặt nhiều công việc để giải quyết nó.
Chris

Tại sao chúng ta không thể sử dụng windows.location.href = URL? Có điều gì sai trong việc sử dụng nó để thay đổi URL và chuyển hướng?
Shan

Tôi không hiểu tại sao không, nhưng tùy chọn sử dụng historycũng hoạt động cho React Native như một tùy chọn cũng như một tùy chọn bổ sung hỗ trợ các trình duyệt cũ.
Chris

Câu trả lời:


308

Bạn có thể sử dụng các historyphương thức bên ngoài các thành phần của bạn. Hãy thử theo cách sau.

Đầu tiên, tạo một historyđối tượng sử dụng gói lịch sử :

// src/history.js

import { createBrowserHistory } from 'history';

export default createBrowserHistory();

Sau đó bọc nó lại <Router>( xin lưu ý , bạn nên sử dụng import { Router }thay vì import { BrowserRouter as Router }):

// src/index.jsx

// ...
import { Router, Route, Link } from 'react-router-dom';
import history from './history';

ReactDOM.render(
  <Provider store={store}>
    <Router history={history}>
      <div>
        <ul>
          <li><Link to="/">Home</Link></li>
          <li><Link to="/login">Login</Link></li>
        </ul>
        <Route exact path="/" component={HomePage} />
        <Route path="/login" component={LoginPage} />
      </div>
    </Router>
  </Provider>,
  document.getElementById('root'),
);

Thay đổi vị trí hiện tại của bạn từ bất kỳ nơi nào, ví dụ:

// src/actions/userActionCreators.js

// ...
import history from '../history';

export function login(credentials) {
  return function (dispatch) {
    return loginRemotely(credentials)
      .then((response) => {
        // ...
        history.push('/');
      });
  };
}

CẬP NHẬT : Bạn cũng có thể thấy một ví dụ hơi khác trong Câu hỏi thường gặp về React Router .


24
Tôi đã cố gắng thực hiện chính xác như những gì @OlegBelostotsky đã nói, nhưng sau đó history.push('some path'), URL thay đổi nhưng trang không thay đổi. Tôi phải đặt window.location.reload()nó sau một số phần trong mã của tôi để làm cho nó hoạt động. Tuy nhiên, trong một trường hợp, tôi phải giữ cây trạng thái redux và tải lại phá hủy nó. Giải pháp nào khác?
sdabrutas

2
@idunno Hãy thử sử dụng thành phần withRouterbậc cao hơn.
Oleg Belostotsky

Điều này đã ném cho tôi một lỗi nêu rõ: createdBrowserHistory không phải là một hàm. Tôi có thể làm gì?
AKJ

@AKJ Có lẽ import createHistory from 'history/createBrowserHistory'; export default createHistory();sẽ làm việc.
Oleg Belostotsky

1
Xin lỗi vì downvote :). Trong khi điều này cũng sẽ hoạt động, cách chính xác để xử lý điều này là cách Chris trả lời: stackoverflow.com/a/42716055/491075 .
gion_13

340

React Router v4 về cơ bản khác với v3 (và trước đó) và bạn không thể làm browserHistory.push()như bạn đã từng.

Thảo luận này có vẻ liên quan nếu bạn muốn biết thêm thông tin:

  • Tạo một tác phẩm mới browserHistorysẽ không hoạt động vì <BrowserRouter>tạo cá thể lịch sử của riêng nó và lắng nghe những thay đổi về điều đó. Vì vậy, một phiên bản khác sẽ thay đổi url nhưng không cập nhật <BrowserRouter>.
  • browserHistory không bị lộ bởi bộ định tuyến phản ứng trong v4, chỉ trong v2.

Thay vào đó, bạn có một vài lựa chọn để làm điều này:

  • Sử dụng thành phần withRouterbậc cao

    Thay vào đó, bạn nên sử dụng withRouterthành phần bậc cao và bọc nó vào thành phần sẽ đẩy vào lịch sử. Ví dụ:

    import React from "react";
    import { withRouter } from "react-router-dom";
    
    class MyComponent extends React.Component {
      ...
      myFunction() {
        this.props.history.push("/some/Path");
      }
      ...
    }
    export default withRouter(MyComponent);

    Kiểm tra tài liệu chính thức để biết thêm thông tin:

    Bạn có thể nhận được quyền truy cập vào các historythuộc tính của đối tượng và gần nhất <Route>matchthông qua các thành phần bậc cao withRouter. withRouter sẽ kết xuất lại thành phần của nó mỗi khi tuyến đường thay đổi với cùng các đạo cụ như <Route>đạo cụ kết xuất : { match, location, history }.


  • Sử dụng contextAPI

    Sử dụng bối cảnh có thể là một trong những giải pháp dễ nhất, nhưng là một API thử nghiệm, nó không ổn định và không được hỗ trợ. Chỉ sử dụng nó khi mọi thứ khác không thành công. Đây là một ví dụ:

    import React from "react";
    import PropTypes from "prop-types";
    
    class MyComponent extends React.Component {
      static contextTypes = {
        router: PropTypes.object
      }
      constructor(props, context) {
         super(props, context);
      }
      ...
      myFunction() {
        this.context.router.history.push("/some/Path");
      }
      ...
    }

    Có một cái nhìn vào các tài liệu chính thức về bối cảnh:

    Nếu bạn muốn ứng dụng của mình ổn định, đừng sử dụng ngữ cảnh. Đây là một API thử nghiệm và có khả năng phá vỡ các bản phát hành React trong tương lai.

    Nếu bạn khăng khăng sử dụng bối cảnh bất chấp những cảnh báo này, hãy thử cách ly việc sử dụng bối cảnh của bạn thành một khu vực nhỏ và tránh sử dụng API ngữ cảnh trực tiếp khi có thể để dễ dàng nâng cấp hơn khi API thay đổi.


9
Có tôi đã thử nó. Cam ơn vi đa hỏi. :-) Vậy làm thế nào để bạn có được bối cảnh vào chức năng hành động này? Cho đến nay, nó đang đến như là không xác định.
Chris

1
Tôi đã nghiên cứu chủ đề này trong một vài ngày nay và không thể làm cho nó hoạt động. Ngay cả khi sử dụng ví dụ trên, tôi vẫn nhận được bộ định tuyến không xác định trong ngữ cảnh. Tôi hiện đang sử dụng phản ứng v15.5.10, Reac-router-dom v4.1.1, prop-type 15.5.10. Các tài liệu xung quanh điều này là thưa thớt và không rõ ràng.
Stu

5
@Stu cái này sẽ hoạt độngthis.context.router.history.push('/path');
Tushar Khatiwada

1
@Chris Thật vậy, nếu bạn cố gắng khởi tạo đối tượng lịch sử và tự mình sử dụng nó, nó sẽ thay đổi url nhưng sẽ không hiển thị thành phần - như bạn đã đề cập ở trên. Nhưng, làm thế nào để sử dụng "history.push" bên ngoài thành phần và lực lượng thành phần kết xuất là tốt?
mát mẻ

52
Điều này không trả lời câu hỏi đang được hỏi đó là cách truy cập history.push NGOÀI TRỜI của một thành phần. Sử dụng withRouter hoặc bối cảnh không phải là tùy chọn khi ở bên ngoài một thành phần.
SunshinyDoyle

49

Bây giờ với Reac-router v5, bạn có thể sử dụng hook vòng đời useHistory như thế này:

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

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

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

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

đọc thêm tại: https://reacttraining.com/react-router/web/api/Hooks/usehistory


1
Đó là một bản cập nhật rất đáng hoan nghênh! Cảm ơn!
Chris

Có cách nào cụ thể mà tôi cần để thiết lập điều này không, tôi đang gọi như sau let history = useHistory();nhưng gặp Object is not callablelỗi, khi tôi thử xem useHistory là console.log(useHistory)gì thì nó hiển thị là không xác định. sử dụng"react-router-dom": "^5.0.1"
steff_bdh

@steff_bdh bạn cần cập nhật nó trong tệp yout pack.json thành "Reac-router-dom": "^ 5.0.1" và chạy 'npm install'
Hadi Abu

2
Đẹp, nhưng không thể sử dụng hook trong các lớp hành động redux vì chúng không phải là thành phần / chức năng React
Jay

Làm thế nào bạn sẽ sử dụng điều này để chuyển hướng khi đăng nhập bằng cách sử dụng (async). Đây là câu hỏi => stackoverflow.com/questions/62154408/ trên
theairbend3r

29

Cách đơn giản nhất trong React Router 4 là sử dụng

this.props.history.push('/new/url');

Nhưng để sử dụng phương thức này, thành phần hiện tại của bạn nên có quyền truy cập vào historyđối tượng. Chúng tôi có thể truy cập bằng

  1. Nếu thành phần của bạn được liên kết Routetrực tiếp, thì thành phần của bạn đã có quyền truy cập vào historyđối tượng.

    ví dụ:

    <Route path="/profile" component={ViewProfile}/>

    Ở đây ViewProfilecó quyền truy cập vào history.

  2. Nếu không kết nối Routetrực tiếp.

    ví dụ:

    <Route path="/users" render={() => <ViewUsers/>}

    Sau đó, chúng ta phải sử dụng withRouter, một phép nối thứ tự cao hơn để làm cong vênh thành phần hiện có.

    ViewUsersThành phần bên trong

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

    • export default withRouter(ViewUsers);

    Đó là bây giờ, ViewUsersthành phần của bạn có quyền truy cập vào historyđối tượng.

CẬP NHẬT

2- trong trường hợp này, chuyển tất cả tuyến propsđến thành phần của bạn và sau đó chúng tôi có thể truy cập this.props.historytừ thành phần ngay cả khi không cóHOC

ví dụ:

<Route path="/users" render={props => <ViewUsers {...props} />}

1
Thông minh! Phương pháp thứ hai của bạn cũng thực hiện thủ thuật cho tôi, vì thành phần của tôi (cần truy cập this.props.history) đến từ HOC, có nghĩa là nó không được liên kết trực tiếp với Route, như bạn giải thích.
cjauvin

25

Đây là cách tôi đã làm nó:

import React, {Component} from 'react';

export default class Link extends Component {
    constructor(props) {
        super(props);
        this.onLogout = this.onLogout.bind(this);
    }
    onLogout() {
        this.props.history.push('/');
    }
    render() {
        return (
            <div>
                <h1>Your Links</h1>
                <button onClick={this.onLogout}>Logout</button>
            </div>
        );
    }
}

Sử dụng this.props.history.push('/cart');để chuyển hướng đến trang giỏ hàng, nó sẽ được lưu trong đối tượng lịch sử.

Thưởng thức đi, Michael.


2
Vâng, có vẻ như trong các thành phần bạn có thể đẩy tốt. Cách duy nhất để tác động đến việc điều hướng bên ngoài một thành phần là chuyển hướng.
Chris

14
Điều này không trả lời câu hỏi đang được hỏi đó là cách truy cập history.push NGOÀI TRỜI của một thành phần. Sử dụng this.props.history không phải là một tùy chọn khi ở bên ngoài một thành phần.
SunshinyDoyle

22

Theo tài liệu React Router v4 - phiên Redux Deep Integration

Cần tích hợp sâu để:

"có thể điều hướng bằng cách gửi hành động"

Tuy nhiên, họ khuyến nghị phương pháp này thay thế cho "tích hợp sâu":

"Thay vì gửi các hành động để điều hướng, bạn có thể chuyển đối tượng lịch sử được cung cấp để định tuyến các thành phần đến hành động của mình và điều hướng với nó ở đó."

Vì vậy, bạn có thể bọc thành phần của mình bằng thành phần bậc cao withRouter:

export default withRouter(connect(null, { actionCreatorName })(ReactComponent));

sẽ chuyển API lịch sử cho các đạo cụ. Vì vậy, bạn có thể gọi người tạo hành động vượt qua lịch sử như một thông số. Ví dụ: bên trong ReactComponent của bạn:

onClick={() => {
  this.props.actionCreatorName(
    this.props.history,
    otherParams
  );
}}

Sau đó, bên trong hành động / index.js của bạn:

export function actionCreatorName(history, param) {
  return dispatch => {
    dispatch({
      type: SOME_ACTION,
      payload: param.data
    });
    history.push("/path");
  };
}

19

Câu hỏi khó chịu, làm tôi mất khá nhiều thời gian, nhưng cuối cùng, tôi đã giải quyết nó theo cách này:

Bọc container của bạn với withRoutervà truyền lịch sử cho hành động của bạn trong mapDispatchToPropschức năng. Trong hành động, sử dụng history.push ('/ url') để điều hướng.

Hoạt động:

export function saveData(history, data) {
  fetch.post('/save', data)
     .then((response) => {
       ...
       history.push('/url');
     })
};

Thùng đựng hàng:

import { withRouter } from 'react-router-dom';
...
const mapDispatchToProps = (dispatch, ownProps) => {
  return {
    save: (data) => dispatch(saveData(ownProps.history, data))}
};
export default withRouter(connect(mapStateToProps, mapDispatchToProps)(Container));

Đây là giá trị Phản ứng Router v4.x .


Cảm ơn, giải pháp withRouter của bạn hoạt động với bản in nhưng nó khá chậm so với trước đây import { createBrowserHistory } from 'history' .
Jay

7

this.context.history.push sẽ không làm việc.

Tôi quản lý để có được đẩy làm việc như thế này:

static contextTypes = {
    router: PropTypes.object
}

handleSubmit(e) {
    e.preventDefault();

    if (this.props.auth.success) {
        this.context.router.history.push("/some/Path")
    }

}

9
Điều này không trả lời câu hỏi đang được hỏi đó là cách truy cập history.push NGOÀI TRỜI của một thành phần. Sử dụng this.context không phải là một tùy chọn khi ở bên ngoài một thành phần.
SunshinyDoyle

6

Trong trường hợp này, bạn đang chuyển đạo cụ cho thunk của bạn. Vì vậy, bạn có thể chỉ cần gọi

props.history.push('/cart')

Nếu đây không phải là trường hợp bạn vẫn có thể truyền lịch sử từ thành phần của bạn

export function addProduct(data, history) {
  return dispatch => {
    axios.post('/url', data).then((response) => {
      dispatch({ type: types.AUTH_USER })
      history.push('/cart')
    })
  }
}

6

Tôi cung cấp thêm một giải pháp trong trường hợp nó có giá trị cho người khác.

Tôi có một history.jstập tin mà tôi có sau đây:

import createHistory from 'history/createBrowserHistory'
const history = createHistory()
history.pushLater = (...args) => setImmediate(() => history.push(...args))
export default history

Tiếp theo, trên Root của tôi nơi tôi xác định bộ định tuyến của mình, tôi sử dụng như sau:

import history from '../history'
import { Provider } from 'react-redux'
import { Router, Route, Switch } from 'react-router-dom'

export default class Root extends React.Component {
  render() {
    return (
     <Provider store={store}>
      <Router history={history}>
       <Switch>
        ...
       </Switch>
      </Router>
     </Provider>
    )
   }
  }

Cuối cùng, actions.jstôi nhập Lịch sử và sử dụng PushLater

import history from './history'
export const login = createAction(
...
history.pushLater({ pathname: PATH_REDIRECT_LOGIN })
...)

Bằng cách này, tôi có thể chuyển sang các hành động mới sau các lệnh gọi API.

Hy vọng nó giúp!


4

Nếu bạn đang sử dụng Redux, thì tôi khuyên bạn nên sử dụng gói npm Reac -router-redux . Nó cho phép bạn gửi các hành động điều hướng cửa hàng Redux.

Bạn phải tạo cửa hàng như được mô tả trong tệp Readme của họ .

Trường hợp sử dụng dễ nhất:

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

this.props.dispatch(push('/second page'));

Trường hợp sử dụng thứ hai với Container / Thành phần:

Thùng đựng hàng:

import { connect } from 'react-redux';
import { push } from 'react-router-redux';

import Form from '../components/Form';

const mapDispatchToProps = dispatch => ({
  changeUrl: url => dispatch(push(url)),
});

export default connect(null, mapDispatchToProps)(Form);

Thành phần:

import React, { Component } from 'react';
import PropTypes from 'prop-types';

export default class Form extends Component {
  handleClick = () => {
    this.props.changeUrl('/secondPage');
  };

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

1
Điều này không hoạt động với Reac-router-redux trừ khi bạn đang sử dụng nextphiên bản vẫn đang được phát triển tại thời điểm này!
froginvasion

4

Tôi đã có thể thực hiện điều này bằng cách sử dụng bind(). Tôi muốn nhấp vào nút index.jsx, đăng một số dữ liệu lên máy chủ, đánh giá phản hồi và chuyển hướng đến success.jsx. Đây là cách tôi làm việc đó ...

index.jsx:

import React, { Component } from "react"
import { postData } from "../../scripts/request"

class Main extends Component {
    constructor(props) {
        super(props)
        this.handleClick = this.handleClick.bind(this)
        this.postData = postData.bind(this)
    }

    handleClick() {
        const data = {
            "first_name": "Test",
            "last_name": "Guy",
            "email": "test@test.com"
        }

        this.postData("person", data)
    }

    render() {
        return (
            <div className="Main">
                <button onClick={this.handleClick}>Test Post</button>
            </div>
        )
    }
}

export default Main

request.js:

import { post } from "./fetch"

export const postData = function(url, data) {
    // post is a fetch() in another script...
    post(url, data)
        .then((result) => {
            if (result.status === "ok") {
                this.props.history.push("/success")
            }
        })
}

success.jsx:

import React from "react"

const Success = () => {
    return (
        <div className="Success">
            Hey cool, got it.
        </div>
    )
}

export default Success

Vì vậy, bằng cách liên kết thisđể postDataindex.jsx, tôi đã có thể truy cập this.props.historyvào request.js... sau đó tôi có thể tái sử dụng chức năng này trong các thành phần khác nhau, chỉ cần phải chắc chắn rằng tôi nhớ để bao gồm this.postData = postData.bind(this)trong constructor().


3

Đây là bản hack của tôi (đây là tệp cấp gốc của tôi, với một chút chuyển hướng trong đó - mặc dù tôi không sử dụng react-router-redux):

const store = configureStore()
const customHistory = createBrowserHistory({
  basename: config.urlBasename || ''
})

ReactDOM.render(
  <Provider store={store}>
    <Router history={customHistory}>
      <Route component={({history}) => {
        window.appHistory = history
        return (
          <App />
        )
      }}/>
    </Router>
  </Provider>,
  document.getElementById('root')
)

Sau đó tôi có thể sử dụng window.appHistory.push()bất cứ nơi nào tôi muốn (ví dụ: trong các chức năng lưu trữ / thunks / sagas của tôi, v.v.) Tôi đã hy vọng tôi chỉ có thể sử dụng window.customHistory.push()nhưng vì một số lý do react-routerdường như không bao giờ cập nhật mặc dù url đã thay đổi. Nhưng theo cách này tôi có react-routersử dụng ví dụ CHÍNH XÁC . Tôi không thích đặt công cụ trong phạm vi toàn cầu và đây là một trong số ít những điều tôi sẽ làm với. Nhưng nó tốt hơn bất kỳ sự thay thế nào khác mà tôi đã thấy IMO.


3

Sử dụng gọi lại. Nó làm việc cho tôi!

export function addProduct(props, callback) {
  return dispatch =>
    axios.post(`${ROOT_URL}/cart`, props, config)
    .then(response => {
    dispatch({ type: types.AUTH_USER });
    localStorage.setItem('token', response.data.token);
    callback();
  });
}

Trong thành phần, bạn chỉ cần thêm gọi lại

this.props.addProduct(props, () => this.props.history.push('/cart'))

3

Vì vậy, cách tôi làm là: - thay vì chuyển hướng sử dụng history.push, tôi chỉ sử dụngRedirect thành phần từ react-router-dom Khi sử dụng thành phần này, bạn có thể vượt qua push=truevà nó sẽ giải quyết phần còn lại

import * as React from 'react';
import { Redirect } from 'react-router-dom';
class Example extends React.Component {
  componentDidMount() {
    this.setState({
      redirectTo: '/test/path'
    });
  }

  render() {
    const { redirectTo } = this.state;

    return <Redirect to={{pathname: redirectTo}} push={true}/>
  }
}

Đây là chính xác mà không phá vỡ chu kỳ kết xuất phản ứng
jzqa

1

React router V4 hiện cho phép sử dụng prop lịch sử như dưới đây:

this.props.history.push("/dummy",value)

Giá trị sau đó có thể được truy cập bất cứ nơi nào có sẵn vị trí prop vì state:{value}không phải là trạng thái thành phần.


1
Điều này không trả lời câu hỏi đang được hỏi đó là cách truy cập history.push NGOÀI TRỜI của một thành phần. Sử dụng this.props.history không phải là một tùy chọn khi ở bên ngoài một thành phần.
Arkady

0

bạn có thể sử dụng nó như thế này khi tôi đăng nhập và điều chỉnh những thứ khác nhau

class Login extends Component {
  constructor(props){
    super(props);
    this.login=this.login.bind(this)
  }


  login(){
this.props.history.push('/dashboard');
  }


render() {

    return (

   <div>
    <button onClick={this.login}>login</login>
    </div>

)

0
/*Step 1*/
myFunction(){  this.props.history.push("/home"); }
/**/
 <button onClick={()=>this.myFunction()} className={'btn btn-primary'}>Go 
 Home</button>

Không cần nhập khẩu!
David Bagdasaryan

1
Mặc dù mã này có thể trả lời câu hỏi, cung cấp ngữ cảnh bổ sung về lý do và / hoặc cách mã này trả lời câu hỏi cải thiện giá trị lâu dài của nó.
rollstuhlfahrer

0

Bước một bọc ứng dụng của bạn trong Bộ định tuyến

import { BrowserRouter as Router } from "react-router-dom";
ReactDOM.render(<Router><App /></Router>, document.getElementById('root'));

Bây giờ toàn bộ Ứng dụng của tôi sẽ có quyền truy cập vào BrowserRouter. Bước hai tôi nhập Tuyến và sau đó chuyển xuống các đạo cụ. Có lẽ trong một trong những tập tin chính của bạn.

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

//lots of code here

//somewhere in my render function

    <Route
      exact
      path="/" //put what your file path is here
      render={props => (
      <div>
        <NameOfComponent
          {...props} //this will pass down your match, history, location objects
        />
      </div>
      )}
    />

Bây giờ nếu tôi chạy console.log (this.props) trong tệp js thành phần của tôi thì tôi sẽ nhận được một cái gì đó trông như thế này

{match: {…}, location: {…}, history: {…}, //other stuff }

Bước 2 Tôi có thể truy cập đối tượng lịch sử để thay đổi vị trí của mình

//lots of code here relating to my whatever request I just ran delete, put so on

this.props.history.push("/") // then put in whatever url you want to go to

Ngoài ra tôi chỉ là một sinh viên bootcamp mã hóa, vì vậy tôi không phải là chuyên gia, nhưng tôi biết bạn cũng có thể sử dụng

window.location = "/" //wherever you want to go

Sửa lỗi cho tôi nếu tôi sai, nhưng khi tôi kiểm tra thì nó đã tải lại toàn bộ trang mà tôi nghĩ đã đánh bại toàn bộ quan điểm sử dụng React.


0

Tạo một tùy chỉnh Routervới riêng nó browserHistory:

import React from 'react';
import { Router } from 'react-router-dom';
import { createBrowserHistory } from 'history';

export const history = createBrowserHistory();

const ExtBrowserRouter = ({children}) => (
  <Router history={history} >
  { children }
  </Router>
);

export default ExtBrowserRouter

Tiếp theo, trên Root của bạn nơi bạn xác định Router, sử dụng như sau:

import React from 'react';       
import { /*BrowserRouter,*/ Route, Switch, Redirect } from 'react-router-dom';

//Use 'ExtBrowserRouter' instead of 'BrowserRouter'
import ExtBrowserRouter from './ExtBrowserRouter'; 
...

export default class Root extends React.Component {
  render() {
    return (
      <Provider store={store}>
        <ExtBrowserRouter>
          <Switch>
            ...
            <Route path="/login" component={Login}  />
            ...
          </Switch>
        </ExtBrowserRouter>
      </Provider>
    )
  }
}

Cuối cùng, nhập historynơi bạn cần và sử dụng nó:

import { history } from '../routers/ExtBrowserRouter';
...

export function logout(){
  clearTokens();      
  history.push('/login'); //WORKS AS EXPECTED!
  return Promise.reject('Refresh token has expired');
}

0

Nếu bạn muốn sử dụng lịch sử trong khi truyền một hàm làm giá trị cho prop của Thành phần, với bộ định tuyến phản ứng 4, bạn có thể chỉ cần cấu trúc historyprop trong thuộc tính kết xuất của <Route/>Thành phần rồi sử dụnghistory.push()

    <Route path='/create' render={({history}) => (
      <YourComponent
        YourProp={() => {
          this.YourClassMethod()
          history.push('/')
        }}>
      </YourComponent>
    )} />

Lưu ý: Để làm việc này, bạn nên bọc Thành phần BrowserRouter của React Router xung quanh thành phần gốc của bạn (ví dụ: có thể có trong index.js)

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.