Animate between sections with useSection hook



This content originally appeared on DEV Community and was authored by Hayyan Hami

Here’s a hook where you can easily use in your sections and it will trigger based on the section coming from or going to. There are 4 directions enter, leave, enterBack, leaveBack.

import { DependencyList, useMemo, useState } from "react";
import usePrevious from "@/hooks/usePrevious";
import { useGlobalStore } from "@/store";
import { Section } from "@/ts/enums";

type Config = {
  pov: Section;
  enter?: (from: Section, back: boolean) => Function | void;
  leave?: (to: Section, back: boolean) => Function | void;
};

export default function useSection(
  getConfig: () => Config,
  deps: DependencyList,
) {
  const section = useGlobalStore((s) => s.section);

  // eslint-disable-next-line react-hooks/exhaustive-deps
  const config = useMemo(getConfig, deps);
  const [target] = useState<Section>(config.pov);

  // same as useEffect but with previous values
  usePrevious<[Section, Config | undefined]>(
    ([fromSection]) => {
      let ejectFn: Function | undefined = undefined;
      // if (fromSection === section) return; // deps updated
      if (section === target) {
        const back = target < fromSection;
        ejectFn = config.enter?.(fromSection, back) ?? undefined;
      } else if (fromSection === target) {
        const back = target > section;
        ejectFn = config.leave?.(section, back) ?? undefined;
      }
      return () => {
        ejectFn?.();
      };
    },
    [section, config],
  );

  const active = useMemo(() => section === target, [section, target]);

  return { section, active };
}


This content originally appeared on DEV Community and was authored by Hayyan Hami