Skip to main content Link Menu Expand (external link) Document Search Copy Copied

useLocationChange

This hook invokes a setter whenever the page location is updated. It uses a window.location like object instead of the actual window.location; the type is exported as RavigerLocation.

API

export interface RavigerLocation {
  /** The current path; alias of `pathname` */
  path: string | null
  /** The current path; alias of `path` */
  pathname: string | null
  /** The full path, ignores any `basePath` in the context */
  fullPath: string
  basePath?: string
  search: string
  hash: string
  host: string
  hostname: string
  href: string
  origin: string
}

export function useLocationChange(
  setFn: (location: RavigerLocation) => void,
  {
    inheritBasePath = true,
    basePath = '',
    isActive,
    onInitial = false,
  }: {
  inheritBasePath?: boolean
  basePath?: string
  isActive?: boolean | (() => boolean)
  onInitial?: boolean
} = {}
): void

Note: options.inheritBasePath defaults to true (even if options is not provided), and takes precedence over options.basePath if true. If no BasePath is in the context to inherit options.basePath will be used as a fallback, if present. If basePath is provided, either by parameter or by context, and is missing from the current path null is sent to the setFn callback.

By default this hook will not run on the initial mount for the component. You can get the location on the first render (mount) by setting onInitial: true in the options argument.

Basic

The first parameter is a setter-function that is invoked with the new RavigerLocation whenever the url is changed. It does not automatically cause a re-render of the parent component (see re-rendering below).

import { useLocationChange } from 'raviger'
import { pageChanged } from './monitoring'

function App () {
  useLocationChange(pageChanged)

  return (
    // ...
  )
}

You should try to provide the same function (referential-equality) to useLocationChange whenever possible. If you are unable to create the function outside the component scope use the useCallback to get a memoized function.

import { useCallback } from 'react'
import { useLocationChange } from 'raviger'
import { pageChanged } from './monitoring'

function App () {
  const onChange = useCallback(location => pageChanged('App', location.path), [])
  useLocationChange(onChange)

  return (
    // ...
  )
}

Conditional Updates

When options.isActive is both defined and falsey the setFn will not be invoked during location changes. If it is undefined or truthy the setFn will be invoked.

Re-rendering

useLocationChange does not itself cause re-rendering. However, it is possible to trigger re-rendering by combining useLocationChange with useState.

import { useState } from 'react'
import { useLocationChange } from 'raviger'

function Route () {
  const [location, setLoc] = useState(null)
  useLocationChange(setLoc, { onInitial: true })

  return (
    // ...
  )
}

Previous Behavior

Prior to v4 this hook called setFn with the path instead of a RavigerLocation. If you prefer the previous behavior you can use this wrapper

export function usePathChange(
  setFn: (path: string | null) => void,
  options: LocationChangeOptionParams = {}
): void {
  useLocationChange(
    useCallback((location: RavigerLocation) => setFn(location.path), [setFn]),
    options
  )
}