@curi/react

About#

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

Installation#

npm install @curi/react
yarn add @curi/react

If you prefer to use script tags, Unpkg will always have the latest version of @curi/react available for you.

<script src="https://unpkg.com/@curi/react@1.0.0-beta.16/dist/curi-react.js" />

There is also a minimized version available if you change the filename to react.min.js. The package will be attached to the window as window.CuriReact.

API#

<CuriBase>#

The <CuriBase> component places values on React's context so that child components can access them.

import { CuriBase } from '@curi/react';
const router = curi(history, routes);

router.respond((response) => {
  ReactDOM.render((
    <CuriBase
      response={response}
      router={router}
      render={response => {
        return response.body ? <response.body /> : null;
      }}
    />
  ), holder);
});

Props#

router#

A router (created by calling curi's curi function).

render#

A render function. This will be called whenever the <CuriBase> renders. The function will be passed the current response object and the router object it was passed as a prop. The function must return a React element.

response#

A response object. You can pass your <CuriBase> a response object and it will use that instead of subscribing to the router. This is ideal for server-side rendering.

action#

The action from the most recent navigation (the second argument passed to router.respond callbacks). This prop is optional.

<Active>#

The <Active> component allows you to style its child component as "active" when the location that <Active> describe matches the current location.

import { Active } from '@curi/react';

The <Active> component lets you modify its children element's props. It takes a merge function as a prop, which you can use to modify the child element's props when the component is "active".

Props#

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.

children#

A React element that will have its props updated when the <Active> component is "active".

merge#

A function that will modify the children element's props. It receives a props object as its argument and must return a props object.

partial#

A boolean that defaults to false. When it is true, the "active" check will check the response's partials array in addition to its name. This allows you to style ancestor routes of the actually "active" route.

Usage#

function merge(props) {
  props.className = 'active';
  return props; 
}

const Users = (props) => (
  {
    props.users.map(u => (
      <Active
        key={u.id}
        name='User'
        merge={merge}
        params={u}
      >
        <User {...u} />
      </Active>
    ))
  }
);

This relies on the active add-on from @curi/addon-active being added to your router.

import createActiveAddon from '@curi/active-addon';

const router = curi(history, routes, {
  addons: [createActiveAddon]
});

While not strictly a requirement, the <Active> relies on the curi and curiResponse context variables existing, so your application should have a <CuriBase> as an ancestor of your <Active>components in order to ensure that those exist.

<Block>#

The <Block> component lets you prevent navigation until a user has confirmed that they want to navigate. This can be useful when the user attempts to navigate away from a partially filled form. This will not prevent the user from navigating to another site, it only works for navigation within the application.

import { Block } from '@curi/react';

Props#

active#

A boolean, which is true by default. When it is true, the navigation block is active. When it is false, navigation will not be blocked.

// will block navigation
<Block active={true} confirm={confirm} />

// will not block navigation
<Block active={false} confirm={confirm} />

confirm#

The confirm prop is a function that will be called whenever there is navigation. The function will receive four arguments: location, action, success, and failure. The location and action values are the location object that is being navigated to and the type of navigation. The success and failure arguments are functions that you should call depending on whether or not you want to let the navigation happen. When the navigation should occur, the confirm function should call the success function. When the navigation should be cancelled, the failure function should be called.

<Block
  confirm={({ location, action }, success, failure) => {
    const response = window.confirm("Shall we?");
    if (response) {
      success();
    } else {
      failure();
    }
  }}
/>

<Curious>#

A component with a render function to pass router, response, and action props to componeonts.

import { Curious } from '@curi/react';
class MyComponent extends React.Component {
  render() {
    return (
      <Curious render={({ router, response, action }) => {
        // pass these props to any components that need them
        return (
          <ThingThatNeedsResponse response={response} />
        );
      }} />
    )
  }
}

export default MyComponent;

Props#

render#

A function that returns a React element. This function will receive an object with router, response and action properties that you can pass to components.
<Curious render={({ router, response, action }) => {...} />

responsive#

By default, the <Curious> component will call its render function whenever a re-render propagates to it. However, if you have navigation blocks in your application (React.PureComponent or shouldComponentUpdate), you can use responsive={true} to trigger re-renders.

<Curious responsive={true} {...} />

router#

By default, the <Curious> component will grab the props it passes to the render function from React's context. However, you might want to make your root Curi component (<CuriBase>) automatically listen for responses. In order to do this, you can pass <Curious> a router and it will listen using that.

<Curious
  responsive={true}
  router={router}
  render={props => <CuriBase render={render} {...props} />}
/>