0

---------App.js------------------------
import "./styles.css";
import { BrowserRouter as Router, Switch, Route } from "react-router-dom";
import Info from "./Info.js";
import Start from "./Start.js";
import End from "./End.js";

export default function App() {
  return (
    <div className="App">
      <Router>
        <Switch>
          <Route path="/" exact component={Start} />
          <Route path="/Info" component={Info} />
          <Route path="/End" component={End} />
        </Switch>
      </Router>
    </div>
  );
}
---------Start.js------------------------
import React from "react";
import { Link } from "react-router-dom";

export default class Start extends React.Component {
  render() {
    return (
      <div>
        <h1>Welcome!</h1>
        <Link to="/Info">
          <button>Next</button>
        </Link>
      </div>
    );
  }
}
---------Info.js------------------------
import React from "react";
import { Link } from "react-router-dom";
import arg from "./Infos.json";

export default class Info extends React.Component {
  constructor() {
    super();
    this.state = {
      i: 0
    };
  }

  clickNext = () => {
    this.setState({ i: this.state.i + 1 });
  };
  clickBack = () => {
    this.setState({ i: this.state.i - 1 });
  };

  arr = arg.map((elem) => elem);

  render() {
    return (
      <div>
        <h1>{this.arr[this.state.i].info}</h1>
        <Link to={this.state.i > 0 ? "/Info" : "/"}>
          <button type="button" onClick={this.clickBack}>
            Back
          </button>
        </Link>
        <Link to={this.state.i < this.arr.length - 1 ? "/Info" : "/End"}>
          <button type="button" onClick={this.clickNext}>
            Next
          </button>
        </Link>
      </div>
    );
  }
}
---------End.js------------------------
import React from "react";
import { Link } from "react-router-dom";

export default class End extends React.Component {
  render() {
    return (
      <div>
        <h1>End!</h1>
        <Link to="/Info">
          <button>Back</button>
        </Link>
      </div>
    );
  }
}

---------Infos.json------------------------
[
  {
    "info": "info 1"
  },
  {
    "info": "info 2"
  },
  {
    "info": "info 3"
  },
  {
    "info": "info 4"
  }
]

So I have: HomeScreen ⇾ Info1 ⇾ Info2 ⇾ Info3 ⇾ EndScreen

Navigating between each of them works perfectly using simple buttons and Router, Switch, Link.

Between InfoScreen-Instances (which later is going to be fetched from an API) is being navigated using one index (array-index) which is being incremented or decremented according to where we are.

My problem is in the EndScreen-Component where I have a back-button, which should take me back to the last Info-Instance (in this example: Info3). The problem is, when I press the back-button in the EndScreen, the first Info-Instance with index 0 (in this example: Info1) is showing up again.

This means the index manipulated in the Info-Component is not being saved, so that I can go back to the same component with this index, when I try to go back from other components (in this example: EndScreen) to the last rendered Info-Component-Instance.

I am using class components (also tried with function components) and I have been trying since long time with too many ways but still have no clue how to do it.


Can anybody suggest how to exactly navigate properly through components???

  • See [react-router go back a page how do you configure history?](https://stackoverflow.com/questions/30915173/react-router-go-back-a-page-how-do-you-configure-history) – Shivam Jha Jun 13 '21 at 14:06

2 Answers2

0

It looks like the problem is that your components are being unmounted when navigating to a new URL (some documentation). Thus, the state is not preserved.

It's difficult to tell what would work best with such a small example or what exactly you're trying to do. Depending on your needs, there are several options for keeping track of the previous info screen.

  1. You can lift state up to a parent component that does not get unmounted each time the URL changes.
  2. If all you need to know is the info screen number of the previous component, and it does not store other state, you can store the info screen number in a query string and you'd be able to get the index from the location object from react-router-dom (when using function components, you would retrieve this object using useLocation().
  3. You could navigate to specific info screens using either query strings or use a slug. To get the value of the slug in a function component, you would use the useParams() hook.

For options 2 and 3, the back button would actually have to go to the previous URL (including the slug or the query string). They also assume that you're only storing the screen index in the info screen's state.

Calvin
  • 443
  • 3
  • 7
0

it seems like you use an older version of react-router-dom. you should use the last version (v6), there are some changes like the Switch has become "Routes" so on . just check it out here https://reactrouter.com/docs/en/v6/getting-started/tutorial and you will solve your problem.

import { Route, BrowserRouter as Router, Routes } from 'react-router-dom';
export default function App() {
  return (
    <div className="App">
      <Router>
        <Routes>
          <Route path="/" element={<Start />} />
          <Route path="/Info" component={<Info >} />
          <Route path="/End" component={<End />} />
        </Routes>
      </Router>
    </div>
  );
}
Zidan Badr
  • 55
  • 1
  • 8