andyh0316
andyh0316

Reputation: 355

reactjs how to go to parent's route in nested routings

Let's say I access directly access from browser the URL

http://localhost:3000/developerList/developer/2

I will have a back button on the page that should go back to parent route, to

http://localhost:3000/developerList/

How can I achieve this? I can't use

history.goBack()

Because that triggers a browser back behavior, which actually goes back to google.com (assuming that's where I came from)

I also can't use

history.push('/developerList') 

because that's not dynamic.

I know this can be done, froming from angular background where you can just do $state.go('^'); and it knows to remove the current route /developer/2 (yes, even the /2 part).

Any chance this can be done in react with libraries or i have to write something. For the life of me I cannot figure it out.

Here is the structure of my routings:

App.js

export class App extends React.Component {
  render() {
    return (
      <Router>
        <Route path='/developerList'>
          <DeveloperListPage></DeveloperListPage>
        </Route>
      </Router>
        );
    }
}

DeveloperListPage.js

export class DeveloperListPage extends React.Component {
  render() {
    return (
      <div className="developer-list-page">
        <Route path='/developerList/developer/:id'>
          <DeveloperPage></DeveloperPage>
        </Route>
      </div>
    )
  }
}

and now in DeveloperPage I wish to have a go back functionality

Upvotes: 2

Views: 3948

Answers (1)

Drew Reese
Drew Reese

Reputation: 202605

At the DeveloperListPage page/component level you can use the current route match to get the path that was matched to render it. Create a gotoParent callback function that uses a history.push to "go back" to this parent component.

Example Code:

App

function App() {
  return (
    <div className="App">
      <Router>
        <ul>
          <li>
            <Link to="/">/home</Link>
          </li>
          <li>
            <Link to="/developerList">/developerList</Link>
          </li>
        </ul>
        <Route path="/developerList">
          <DeveloperListPage />
        </Route>
      </Router>
    </div>
  );
}

DeveloperListPage

const DeveloperListPage = () => {
  const history = useHistory();
  const { path } = useRouteMatch(); // get matched path

  const gotoParent = () => history.push(path); // go to this path

  return (
    <div className="developer-list-page">
      <ul>
          <li>
            <Link
              to={`/developerList/developer/${Math.floor(
                Math.random() * 1000
              )}`}
            >
              /developerList/developer/:id
            </Link>
          </li>
        </ul>
      <Route path="/developerList/developer/:id">
        <DeveloperPage gotoParent={gotoParent} /> // <-- pass callback
      </Route>
    </div>
  );
};

DeveloperPage

const DeveloperPage = ({ gotoParent }) => { // <-- destructure callback
  const history = useHistory();
  const { id } = useParams();
  return (
    <div>
      Developer Page: {id}
      <div>
        <button onClick={gotoParent} type="button"> // <-- attach callback
          Go to parent
        </button>
        <button onClick={history.goBack} type="button">
          Go Back
        </button>
      </div>
    </div>
  );
};

Demo

Initial URL: "/developerList/developer/174"

  • Try the "Go Back" button
  • Try the "Go to Parent" button and see difference

Edit reactjs-how-to-go-to-parents-route-in-nested-routings

Note: If you don't want to explicitly pass "gotoParent" callbacks to children routes you could easily abstract this into a React context to provide a "nearest" parent component to jump to.

Upvotes: 1

Related Questions