W obecnej wersji React Router (v3) mogę zaakceptować odpowiedź serwera i użyć browserHistory.push
, aby przejść do odpowiedniej strony z odpowiedzią. Jednak to nie jest'dostępne w v4, a ja'nie jestem pewien, jaki jest właściwy sposób radzenia sobie z tym.
W tym przykładzie, używając Redux, components/app-product-form.js wywołuje this.props.addProduct(props)
kiedy użytkownik przesyła formularz. Kiedy serwer zwraca sukces, użytkownik jest przenoszony na stronę koszyka.
// 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
});
}
Jak mogę zrobić przekierowanie na stronę Cart z funkcji dla React Router v4?
React Router v4 jest zasadniczo różny od v3 (i wcześniejszych) i nie można zrobić browserHistory.push()
jak kiedyś.
Ta dyskusja wydaje się powiązana, jeśli chcesz uzyskać więcej informacji:
- Tworzenie nowej
browserHistory
won't work because<BrowserRouter>
creates its own history instance, and listens for changes on that. Więc inna instancja zmieni adres url, ale nie zaktualizuje<BrowserRouter>
.- BrowserHistory` nie jest eksponowane przez react-router w v4, tylko w v2.
Zamiast tego masz kilka opcji, aby to zrobić:
Zamiast tego powinieneś użyć komponentu wysokiego rzędu withRouter
i zawinąć go do komponentu, który będzie pchał do historii. Na przykład:
<!-- language: lang-js -->
importuj React z "react";
import { withRouter } from "react-router-dom";
class MyComponent extends React.Component {
...
myFunction() {
this.props.history.push("/some/Path");
}
...
}
export default withRouter(MyComponent);
Sprawdź oficjalną dokumentację po więcej informacji:
Możesz uzyskać dostęp do właściwości obiektu
historia
oraz najbliższego<Route>
'smatch
poprzez komponent wyższego rzędu withRouter. withRouter będzie renderował swój komponent za każdym razem, gdy zmieni się trasa z tymi samymi rekwizytami, co<Route>
renderuje rekwizyty:{ match, location, history }
.
kontekstu
Użycie kontekstu może być jednym z najprostszych rozwiązań, ale będąc eksperymentalnym API jest niestabilne i niewspierane. Używaj go tylko wtedy, gdy wszystko inne zawiedzie. Oto'przykład:
<!-- language: lang-js -->
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");
}
...
}
Spójrz na oficjalną dokumentację na temat kontekstu:
Jeśli chcesz, aby Twoja aplikacja była stabilna, don't używaj kontekstu. Jest to eksperymentalne API i prawdopodobnie ulegnie uszkodzeniu w przyszłych wydaniach Reacta.
Jeśli nalegasz na używanie kontekstu pomimo tych ostrzeżeń, spróbuj odizolować swoje użycie kontekstu do małego obszaru i unikaj używania API kontekstu bezpośrednio, gdy jest to możliwe, aby łatwiej było uaktualnić, gdy API się zmieni.
Oto jak ja to zrobiłem:
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>
);
}
}
Użyj this.props.history.push('/cart');
aby przekierować na stronę koszyka, zostanie ona zapisana w obiekcie historii.
Ciesz się, Michael.
this.context.history.push
nie będzie działać.
Udało mi się uzyskać push działający w ten sposób:
static contextTypes = {
router: PropTypes.object
}
handleSubmit(e) {
e.preventDefault();
if (this.props.auth.success) {
this.context.router.history.push("/some/Path")
}
}