DEV Community

Pedro Palhari for teepad

Posted on

Creating a stack navigator, with proper animations, using Ionic and React.

So, I've been really diggin' the Ionic and React integration. I usually add it to an already existing React application and go from there.

But, recently, I've stumbled upon something. I want to control the direction of my transitions between pages.

And the docs, they sure do provide something to work with. You can pass a prop called routeDirection to some specific Ionic components. But you can't control it with code.

But, I, want to control the direction of my transitions, with my own code, so I started looking into it.

It happens that these transitions are actually part of a Context called NavContext inside @ionic/react, so you can just:

import { useContext } from "react";
import { NavContext } from "@ionic/react";

function MyComponent(){
  let navigationContext = useContext(NavContext);

  //forbidden by the gods, a back-animated-push
  navigationContext.navigate("/route", "back"); 

So, to create a stack animator, all you need is a hook to handle the screens you've passed, and one singleton array shared between them:


import { useContext } from "react";
import { NavContext } from "@ionic/react";

//Hook to encapsulate navigation context
export function useContextNavigation() {
  let navigation = useContext(NavContext);

  return navigation;

let stack: string[] = ["/"];
export function useStackNavigation() {
  let navigation = useContextNavigation();


  function navigateTo(screen: string) {
    let indexOfScreenOnStack = stack.indexOf(screen);
    if (indexOfScreenOnStack != -1) {
      if (indexOfScreenOnStack == stack.length - 1) return;

      stack = stack.slice(0, indexOfScreenOnStack);
      navigation.navigate(screen, "back");
    } else {
      navigation.navigate(screen, "forward");

  return navigateTo;

And done! You'd need to pass extra parameters to the navigateTo function if you want to handle state, but that is simple enough.

Alt Text

I spent some time working around a solution, and that seems to do it.

For reference, the versions I'm using of Ionic and Ionic/React are:

  version "5.0.0"
  resolved ""
  integrity sha512-IjBSZtel1W9zJvdwI9Z8LOHS9eOWhulumiTuvG2yD1Qj6dQ8Cp67zOYdHhxkhH2JBnxILC+vJgXp/0pnEFIu2Q==
    tslib "*"

  version "5.0.0"
  resolved ""
  integrity sha512-Q6uPAyWa01XLoZ7MdeM0xRKID8SR/hFuoGIjXFlawq2TKwiPCZbSjegHXdFHcX0LHTC/iQuu4Ly2d8UaD5ljZQ==
    "@ionic/core" "5.0.0"
    ionicons "^5.0.0"
    tslib "*"

Top comments (0)