Come spingere alla cronologia in React Router v4?

Nella versione attuale di React Router (v3) posso accettare una risposta del server e usare browserHistory.push per andare alla pagina di risposta appropriata. Tuttavia, questo non è disponibile nella v4, e non sono sicuro di quale sia il modo appropriato per gestire questo.

In questo esempio, usando Redux, components/app-product-form.js chiama this.props.addProduct(props) quando un utente invia il modulo. Quando il server restituisce un successo, l'utente viene portato alla pagina del carrello.

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

Come posso fare un reindirizzamento alla pagina del carrello dalla funzione per React Router v4?

React Router v4 è fondamentalmente diverso dalla v3 (e precedenti) e non si può fare browserHistory.push() come si faceva prima.

Questa discussione sembra correlata se vuoi maggiori informazioni:

Creare una nuova browserHistory non funzionerà perché crea la sua istanza di storia, e ascolta i cambiamenti su quella. Quindi un'istanza diversa cambierà l'url ma non aggiornerà il.

  • La browserHistory non è esposta da react-router in v4, solo in v2.

Invece hai alcune opzioni per farlo:

  • Utilizzare il componente di ordine superiore `withRouter

Invece si dovrebbe usare il componente di alto ordine withRouter, e avvolgerlo al componente che spingerà alla cronologia. Per esempio:

-- lingua: lang-js -->

    import React da "react";
    import { withRouter } da "react-router-dom";

    classe MyComponent estende React.Component {
      ...
      myFunction() {
        this.props.history.push("/some/Path");
      }
      ...
    }
    export default withRouter(MyComponent);

Controlla la documentazione ufficiale per maggiori informazioni:

È possibile accedere alle proprietà dell'oggetto history e al ``'s match più vicino tramite il componente di ordine superiore withRouter. withRouter renderà nuovamente il suo componente ogni volta che la rotta cambia con gli stessi oggetti di scena di `` render: { match, location, history }.


  • Usa l'API context.

Usare il contesto potrebbe essere una delle soluzioni più semplici, ma essendo un'API sperimentale è instabile e non supportata. Usala solo quando tutto il resto fallisce. Ecco un esempio:

Lingua: lang-js -->

    import React da "react";
    importa PropTypes da "prop-types";

    classe MyComponent estende React.Component {
      static contextTypes = {
        router: PropTypes.object
      }
      constructor(props, context) {
         super(props, context);
      }
      ...
      myFunction() {
        this.context.router.history.push("/some/Path");
      }
      ...
    }

Date un'occhiata alla documentazione ufficiale su context:

Se vuoi che la tua applicazione sia stabile, non usare context. È un'API sperimentale ed è probabile che si rompa nelle future versioni di React.

Se insistete nell'usare il contesto nonostante questi avvertimenti, cercate di isolare il vostro uso del contesto ad una piccola area ed evitate di usare direttamente l'API del contesto quando possibile in modo che sia più facile aggiornare quando l'API cambia.

Commentari (13)

Ecco come ho fatto:

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>
                Logout
            </div>
        );
    }
}

Usa this.props.history.push('/cart'); per reindirizzare alla pagina del carrello che sarà salvata nell'oggetto storia.

Buon divertimento, Michael.

Commentari (3)

this.context.history.push non funzionerà.

Sono riuscito a far funzionare push in questo modo:

static contextTypes = {
    router: PropTypes.object
}

handleSubmit(e) {
    e.preventDefault();

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

}
Commentari (1)