@curi/react-dom

GitHub logoGitHub RepoNPM logoNPM Package

Installation

The package can be installed through npm (you need to have Node & NPM installed).

npm install @curi/react-dom

Prefer inline scripts? A full (.umd.js) and minified (.min.js) script is available for every version through Unpkg. You can access the package's exports through window.CuriReactDOM.

About

The @curi/react-dom package provides a number of React components that you can use for rendering your application.

For more information on using Curi with React DOM, please check out the React DOM guide.

API

curiProvider()

A higher-order component that returns a Router component.

import { curiProvider } from '@curi/react-dom';

const router = curi(history, routes);
const Router = curiProvider(router);

ReactDOM.render((
  <Router>
    <App />
  </Router>
), node);
Note:

Why a higher-order component not regular component? Props signify values that can change, but an application should only ever have one router. Using a higher-order component hard-codes the provided router as the one and only router.

Router

The Router sets routing context data. Any component that relies on routing data must be a descendant of the Router.

children

The Router takes any valid React node (elements, strings, etc.) as its children.

useCuri()

The useCuri hook reads the current response, navigation, and router values from React's context.

import { useCuri } from '@curi/react-dom';

function App() {
  const {
    response,
    navigation,
    router
  } = useCuri();
  return (
    <ThingThatNeedsResponse
      response={response}
    />
  );
}

useActive()

The useActive hook determines if a route is active by comparing a route name (and possibly params) to a response object.

import { useActive, Link } from '@curi/react-dom';

function ActiveLink({
  name,
  params,
  partial,
  children
}) {
  const active = useActive({ name, params, partial });
  return (
    <Link
      name={name}
      params={params}
      forward={{ className: active ? "active" : "" }}
    >
      {children}
    </Link>
  );
}

<ActiveLink name="Home">Home</ActiveLink>
Note:

useActive relies on the active route interaction from @curi/route-active being added to your router.

import active from '@curi/route-active';

const router = curi(history, routes, {
  route: [active()]
});

Options

useActive takes a single argument, an options object.

name

The name of the route to compare against the response object.

params

An object containing route parameters. These will be compared against the route params of the response object.

partial

Allows ancestor routes to be considered active when true. Defaults to false.

// response = { name: "User Album", params: { id: "abcde" }}
// where "User Album" is a child route of "User"

useActive({ name: "User" }); // false
useActive({ name: "User", partial: true }); // true

locationCheck

The base active check only checks that the route (i.e. pathname) is active. locationCheck allows you to check if other parts of the location are also active.

useActive({
  name: "Results",
  locationCheck: loc => loc.query === "page=3"
});

// active for /results?page=3
// not active for /results?page=1

useNavigationFocus()

The useNavigationFocus hook is used to focus a DOM element.

Note:

The DOM component that gets the ref should either already be "focusable", like an <input>, or be given a tabIndex prop (usually with the value of -1). If neither of these conditions is met, then the document's <body> will be focused.

import { useNavigationFocus } from "@curi/react-dom";

function App() {
  const ref = React.createRef(null);
  useNavigationFocus(ref);

  return (
    <div tabIndex={-1} ref={ref}>
      {/* ... */}
    </div>
  );
}

The focused element will have an outline (the exact style varies by browser). You can remove this with CSS by setting outline to "none".

<div
  ref={ref}
  tabIndex={-1}
  style={{ outline: "none" }}
>
  {/* ... */}
</div>

Options

preventScroll

The default behavior for focusing an element is to scroll to it. If you want to prevent this, set preventScroll to true.

// scrolls
useNavigationFocus(ref);

// does not scroll
useNavigationFocus(ref, { preventScroll: true });

preserve

The default focus behavior is to always focus the element that the ref is attached to. However, if you want to preserve the focus on some other element (e.g. an autofocused element), setting the preserve option to true will stop the ref element from claiming the focus.

This only works when the already-focused element is a child of the ref element. If it is not a child, then the ref element will take the focus.

// claim focus for the <div>
useNavigationFocus(ref)
<div tabIndex={-1} ref={ref}>
  <input autoFocus={true} />
</div>

// preserve focus on the <input>
useNavigationFocus(ref, { preserve: true });
<div tabIndex={-1} ref={ref}>
  <input autoFocus={true} />
</div>

useNavigating()

The useNavigating hook is used to determine if the application is currently navigating. When the application is navigating, it returns a function to cancel the navigation.

This is only useful for asynchronous routes because with synchronous routes, navigation happens immediately.

import { useNavigating } from "@curi/react-dom";

function CancelNavigation() {
  const cancel = useNavigating();

  return cancel
    ? <button onClick={cancel}>Cancel</button>
    : null;
}
Note:

Ideally, browsers would natively handle asynchronous navigation and this would be unnecessary. For the time being, this is the next best solution.

useBlock()

The useBlock hook lets you setup navigation blocks. Navigation away from the page will be prevented unless the user confirms that they want to navigate.

The primary use case for useBlock is to prevent accidental navigation away from a page with a a partially filled form.

Note:

This will not prevent the user from navigating to another site, it only works for navigation within the application.

import { useBlock } from '@curi/react-dom';
        
useBlock(true, confirm);

Arguments

active

Navigation is only blocked when active is true.

// will block navigation
useBlock(true, confirm);

// will not block navigation
useBlock(false, confirm);

fn

A function that will be called whenever there is navigation. The function is passed three arguments: info, confirm, and prevent.

useBlock(true, (info, success, failure) => {
  const response = window.confirm("Shall we?");
  if (response) {
    success();
  } else {
    failure();
  }
});
info

info is an object which contains information about the navigation. The object has three properties:

  • to - the navigation location
  • from - the current location
  • action - the type of navigation (PUSH, REPLACE, or POP).
confirm

A function that should be called when the user confirms that they want to navigate.

prevent

A function that should be called when the use wants to cancel the navigation.

useLocation()

The useLocation hook creates a location object.

import { useLocation } from '@curi/react-dom';
        
useLocation({
  name: "Video",
  params: { id: "jaifeo9" } },
  hash: "comments",
  query: "t=15"
});

Options

name

The name of the route to generate the location's pathname from. If this is not provided, the generated location's pathname will be an empty string ("");

params

An object of params for the named route.

hash

A hash string for the location.

query

The location's query value.

By default, this is expected to be a string, but if you configure your history object with the query option, this may be something else.

state

State data to associate with the location. This must be serializable.

useHref()

The useHref hook creates a URL string.

import { useHref } from '@curi/react-dom';
        
const href = useHref({
  name: "Video",
  params: { id: "jaifeo9" } },
  hash: "comments",
  query: "t=15"
});
// href = "/video/jaifeo9?t=15#comments"

Options

name

The name of the route to generate the location's pathname from. If this is not provided, the generated location's pathname will be an empty string ("");

params

An object of params for the named route.

hash

A hash string for the location.

query

The location's query value.

By default, this is expected to be a string, but if you configure your history object with the query option, this may be something else.

<Curious>

A context consumer component for injecting router values into components.

import { Curious } from '@curi/react-dom';

function MyComponent() {
  return (
    <Curious>
      {({ router, response, navigation }) => {
        // pass these props to any components
        // that needs them
        return (
          <ThingThatNeedsResponse
            response={response}
          />
        );
      }}
    </Curious>
  );
}

Props

children

A render-invoked function that returns a React element. This function will receive an object with router, response and navigation properties.