javascript - react-router gå tilbake en side hvordan konfigurerer du historikk?
Kan noen vennligst fortelle meg hvordan jeg kan gå tilbake til forrige side i stedet for en spesifikk rute?
Når du bruker denne koden:
var BackButton = React.createClass({
mixins: [Router.Navigation],
render: function() {
return (
<button
className="button icon-left"
onClick={this.navigateBack}>
Back
</button>
);
},
navigateBack: function(){
this.goBack();
}
});
Få denne feilen, goBack() ble ignorert fordi det ikke finnes noen ruterhistorikk
Her er mine ruter:
// Routing Components
Route = Router.Route;
RouteHandler = Router.RouteHandler;
DefaultRoute = Router.DefaultRoute;
var routes = (
<Route name="app" path="/" handler={OurSchoolsApp}>
<DefaultRoute name="home" handler={HomePage} />
<Route name="add-school" handler={AddSchoolPage} />
<Route name="calendar" handler={CalendarPage} />
<Route name="calendar-detail" path="calendar-detail/:id" handler={CalendarDetailPage} />
<Route name="info-detail" path="info-detail/:id" handler={InfoDetailPage} />
<Route name="info" handler={InfoPage} />
<Route name="news" handler={NewsListPage} />
<Route name="news-detail" path="news-detail/:id" handler={NewsDetailPage} />
<Route name="contacts" handler={ContactPage} />
<Route name="contact-detail" handler={ContactDetailPage} />
<Route name="settings" handler={SettingsPage} />
</Route>
);
Router.run(routes, function(Handler){
var mountNode = document.getElementById('app');
React.render(<Handler /> , mountNode);
});
Svar #1
Bruke React Hooks
Import :
import { useHistory } from "react-router-dom";
I en statsløs komponent:
let history = useHistory();
Kall hendelsen:
history.goBack()
Eksempler bruker i hendelsen Knapp:
<button onClick={history.goBack}>Back</button>
eller
<button onClick={() => history.goBack()}>Back</button>
Svar #2
Oppdater med React v16 og ReactRouter v4.2.0 (oktober 2017):
class BackButton extends Component {
static contextTypes = {
router: () => true, // replace with PropTypes.object if you use them
}
render() {
return (
<button
className="button icon-left"
onClick={this.context.router.history.goBack}>
Back
</button>
)
}
}
Oppdater med React v15 og ReactRouter v3.0.0 (august 2016):
var browserHistory = ReactRouter.browserHistory;
var BackButton = React.createClass({
render: function() {
return (
<button
className="button icon-left"
onClick={browserHistory.goBack}>
Back
</button>
);
}
});
Lagde en fiddle med et litt mer komplekst eksempel med en innebygd iframe: https://jsfiddle.net/kwg1da3a/
React v14 og ReactRouter v1.0.0 (10. sep. 2015)
Du kan gjøre dette:
var React = require("react");
var Router = require("react-router");
var SomePage = React.createClass({
...
contextTypes: {
router: React.PropTypes.func
},
...
handleClose: function () {
if (Router.History.length > 1) {
// this will take you back if there is history
Router.History.back();
} else {
// this will take you to the parent route if there is no history,
// but unfortunately also add it as a new route
var currentRoutes = this.context.router.getCurrentRoutes();
var routeName = currentRoutes[currentRoutes.length - 2].name;
this.context.router.transitionTo(routeName);
}
},
...
Du må være forsiktig med at du har den nødvendige historikken for å gå tilbake. Hvis du går direkte til siden og deretter trykker tilbake, vil det ta deg tilbake i nettleserhistorikken før appen din.
Denne løsningen vil ta seg av begge scenariene. Den vil imidlertid ikke håndtere en iframe som kan navigere innenfor siden (og legge til i nettleserens historikk), med tilbakeknappen. Ærlig talt, jeg synes det er en feil i react-router. Problem opprettet her: https://github.com/rackt/react-router/issues/1874
Svar #3
React Router v6
useNavigate-hooken er den anbefalte måten å gå tilbake på nå:
import { useNavigate } from 'react-router-dom';
function App() {
const navigate = useNavigate();
return (
<>
<button onClick={() => navigate(-1)}>go back</button>
<button onClick={() => navigate(1)}>go forward</button>
</>
);
}
Codesandbox-eksempel (ødelagt lenke)
Gå tilbake/frem flere historikkstakkoppføringer:
<button onClick={() => navigate(-2)}>go two back</button>
<button onClick={() => navigate(2)}>go two forward</button>
Gå til spesifikk rute:
navigate("users") // go to users route, like history.push
navigate("users", { replace: true }) // go to users route, like history.replace
navigate("users", { state }) // go to users route, pass some state in
useNavigate erstatter useHistory for å støtte kommende React Suspense/Concurrent-modus bedre.
Svar #4
import
withRouterimport { withRouter } from 'react-router-dom';Eksporter komponenten din som:
export withRouter(nameofcomponent)Eksempel, på knappetrykk, kall
goBack:<button onClick={this.props.history.goBack}>Back</button>
Testet på react-router-dom v4.3
Svar #5
Jeg tror du bare trenger å aktivere BrowserHistory på ruteren din ved å initialisere det slik: <Router history={new BrowserHistory}>.
Før det bør du kreve BrowserHistory fra 'react-router/lib/BrowserHistory'
Her er et eksempel som bruker ES6
const BrowserHistory = require('react-router/lib/BrowserHistory').default;
const App = React.createClass({
render: () => {
return (
<div><button onClick={BrowserHistory.goBack}>Go Back</button></div>
);
}
});
React.render((
<Router history={BrowserHistory}>
<Route path="/" component={App} />
</Router>
), document.body);
Svar #6
this.context.router.goBack()
Ingen navigasjonsblanding kreves!
Svar #7
ES6-metode uten mixins som bruker react-router, statsløs funksjon.
import React from 'react'
import { browserHistory } from 'react-router'
export const Test = () => (
<div className="">
<button onClick={browserHistory.goBack}>Back</button>
</div>
)
Svar #8
Gå tilbake til spesifikk side:
import { useHistory } from "react-router-dom";
const history = useHistory();
const routeChange = () => {
let path = '/login';
history.push(path);
};
Gå tilbake til forrige side:
import { useHistory } from "react-router-dom";
const history = useHistory();
const routeChange = () => {
history.goBack()
};
Svar #9
Sjekk ut mitt fungerende eksempel som bruker React 16.0 med React-router v4. Sjekk ut koden på Github
Bruk withRouter og history.goBack()
Dette er ideen jeg implementerer...
History.js
import React, { Component } from 'react';
import { withRouter } from 'react-router-dom'
import './App.css'
class History extends Component {
handleBack = () => {
this.props.history.goBack()
}
handleForward = () => {
console.log(this.props.history)
this.props.history.go(+1)
}
render() {
return <div className="container">
<div className="row d-flex justify-content-between">
<span onClick={this.handleBack} className="d-flex justify-content-start button">
<i className="fas fa-arrow-alt-circle-left fa-5x"></i>
</span>
<span onClick={this.handleForward} className="d-flex justify-content-end button">
<i className="fas fa-arrow-alt-circle-right fa-5x"></i>
</span>
</div>
</div>
}
}
export default withRouter(History)
PageOne.js
import React, { Fragment, Component } from 'react'
class PageOne extends Component {
componentDidMount(){
if(this.props.location.state && this.props.location.state.from != '/pageone')
this.props.history.push({
pathname: '/pageone',
state: {
from: this.props.location.pathname
}
});
}
render() {
return (
<Fragment>
<div className="container-fluid">
<div className="row d-flex justify-content-center">
<h2>Page One</h2>
</div>
</div>
</Fragment>
)
}
}
export default PageOne
p.s. beklager, koden er for stor til å legge ut alt her
Svar #10
Dette fungerer med nettleser- og hash-historikk.
this.props.history.goBack();
Svar #11
Dette er en fungerende BackButton-komponent (React 0.14):
var React = require('react');
var Router = require('react-router');
var History = Router.History;
var BackButton = React.createClass({
mixins: [ History ],
render: function() {
return (
<button className="back" onClick={this.history.goBack}>{this.props.children}</button>
);
}
});
module.exports = BackButton;
Du kan selvfølgelig gjøre noe slikt hvis det ikke finnes noen historikk:
<button className="back" onClick={goBack}>{this.props.children}</button>
function goBack(e) {
if (/* no history */) {
e.preventDefault();
} else {
this.history.goBack();
}
}
Svar #12
For react-router v2.x har dette endret seg. Her er hva jeg gjør for ES6:
import React from 'react';
import FontAwesome from 'react-fontawesome';
import { Router, RouterContext, Link, browserHistory } from 'react-router';
export default class Header extends React.Component {
render() {
return (
<div id="header">
<div className="header-left">
{
this.props.hasBackButton &&
<FontAwesome name="angle-left" className="back-button" onClick={this.context.router.goBack} />
}
</div>
<div>{this.props.title}</div>
</div>
)
}
}
Header.contextTypes = {
router: React.PropTypes.object
};
Header.defaultProps = {
hasBackButton: true
};
Header.propTypes = {
title: React.PropTypes.string
};
Svar #13
I react-router v4.x kan du bruke history.goBack som er ekvivalent med history.go(-1).
App.js
import React from "react";
import { render } from "react-dom";
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
import Home from "./Home";
import About from "./About";
import Contact from "./Contact";
import Back from "./Back";
const styles = {
fontFamily: "sans-serif",
textAlign: "left"
};
const App = () => (
<div style={styles}>
<Router>
<div>
<ul>
<li><Link to="/">Home</Link></li>
<li><Link to="/about">About</Link></li>
<li><Link to="/contact">Contact</Link></li>
</ul>
<hr />
<Route exact path="/" component={Home} />
<Route path="/about" component={About} />
<Route path="/contact" component={Contact} />
<Back />{/* <----- This is component that will render Back button */}
</div>
</Router>
</div>
);
render(<App />, document.getElementById("root"));
Back.js
import React from "react";
import { withRouter } from "react-router-dom";
const Back = ({ history }) => (
<button onClick={history.goBack}>Back to previous page</button>
);
export default withRouter(Back);
Demo: https://codesandbox.io/s/ywmvp95wpj
Vennligst husk at ved å bruke history kan brukerne dine forlate siden fordi history.goBack() kan laste en side som besøkende har besøkt før de åpnet applikasjonen din.
For å forhindre en slik situasjon som beskrevet ovenfor, har jeg laget et enkelt bibliotek react-router-last-location som overvåker brukerens siste posisjon.
Bruken er veldig enkel. Først må du installere react-router-dom og react-router-last-location fra npm.
npm install react-router-dom react-router-last-location --save
Bruk deretter LastLocationProvider som vist nedenfor:
App.js
import React from "react";
import { render } from "react-dom";
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
import { LastLocationProvider } from "react-router-last-location";
// ↑
// |
// |
//
// Import provider
//
import Home from "./Home";
import About from "./About";
import Contact from "./Contact";
import Back from "./Back";
const styles = {
fontFamily: "sans-serif",
textAlign: "left"
};
const App = () => (
<div style={styles}>
<h5>Click on About to see your last location</h5>
<Router>
<LastLocationProvider>{/* <---- Put provider inside <Router> */}
<div>
<ul>
<li><Link to="/">Home</Link></li>
<li><Link to="/about">About</Link></li>
<li><Link to="/contact">Contact</Link></li>
</ul>
<hr />
<Route exact path="/" component={Home} />
<Route path="/about" component={About} />
<Route path="/contact" component={Contact} />
<Back />
</div>
</LastLocationProvider>
</Router>
</div>
);
render(<App />, document.getElementById("root"));
Back.js
import React from "react";
import { Link } from "react-router-dom";
import { withLastLocation } from "react-router-last-location";
// ↑
// |
// |
//
// `withLastLocation` higher order component
// will pass `lastLocation` to your component
//
// |
// |
// ↓
const Back = ({ lastLocation }) => (
lastLocation && <Link to={lastLocation || '/'}>Back to previous page</Link>
);
// Remember to wrap
// your component before exporting
//
// |
// |
// ↓
export default withLastLocation(Back);
Demo: https://codesandbox.io/s/727nqm99jj
Svar #14
Jeg vil oppdatere de tidligere svarene litt. Hvis du bruker react-router >v6.0, er ikke useHistory() den riktige måten å gå tilbake på. Du vil få en feil, siden jeg antar at useHistory() ikke er til stede i den nyeste versjonen. Så dette er det oppdaterte svaret.
// This is a React Router v6 app
import { useNavigate } from "react-router-dom";
function App() {
const navigate = useNavigate();
return (
<>
<button onClick={() => navigate(-2)}>
Go 2 pages back
</button>
<button onClick={() => navigate(-1)}>Go back</button>
<button onClick={() => navigate(1)}>
Go forward
</button>
<button onClick={() => navigate(2)}>
Go 2 pages forward
</button>
</>
);
}
Bruk denne useNavigate() hooken. Du kan lese den offisielle dokumentasjonen for denne overgangen fra v5 til v6 her https://reactrouter.com/docs/en/v6/upgrading/v5
