3.3.4 • Published 2 years ago

react-location v3.3.4

Weekly downloads
86
License
MIT
Repository
github
Last release
2 years ago

React-Location

⚛️ React utilities for location routing, params, queries, and hashes.

React-Location is a Router for React. It's been built with the following considerations in mind:

  • Clean and clear routing syntax
  • Familiar API for productivity
  • Functional query params & URL parsing
  • Complex Link generation
  • Relative Routing + Links
  • Both Colocated or Nested Route structure
  • Programmatic Navigation
  • Hooks for ease-of-use
  • Support for URL or in-memory location sources

Get Started

  1. Install react-location
yarn add react-location
# or
npm i -s react-location
  1. Import and use react-location
import { React } from "react";
import { render } from "react-dom";
import { LocationProvider, Match, MatchFirst, Link } from "react-location";

render(
  <LocationProvider>
    <nav>
      <Link to="/">Home</Link>
      <Link to="dashboard">Dashboard</Link>
      <Link to="invoices">Invoices</Link>
    </nav>
    <div>
      <Match path="/">
        <div>This is Home</div>
      </Match>
      <Match path="dashboard">
        <div>This is the Dashboard</div>
      </Match>
      <MatchFirst>
        <Match path="invoices">
          <div>These are the invoices</div>
          <ul>
            <li>
              <Link to="1">Invoice 1</Link>
            </li>
            <li>
              <Link to="2">Invoice 2</Link>
            </li>
            <li>
              <Link to="3">Invoice 3</Link>
            </li>
          </ul>
        </Match>
        <Match path=":invoiceID">
          {({ params }) => (
            <div>
              <Link to="..">Back</Link>
              This is invoice #{params.invoiceID}
            </div>
          )}
        </Match>
      </MatchFirst>
    </div>
  </LocationProvider>
);

Components

LocationProvider

Required: true

The LocationProvider component is the root Provider component for react-location in your app. Render it at least once in the highest sensible location within your application. You can also use this component to preserve multiple location instances in the react tree at the same, which is useful for things like route animations or location mocking.

PropRequiredDescription
historyfalseThe history object to be used internally by react-location
basepathfalseThe basepath prefix for all URLs (not-supported for memory source histories)
locationfalseA custom location to use instead of creating a new one. If a location is passed here, all other props will be ignored and will be inherited from the custom location instead. This useful for things like animation or preserving multiple locations in the tree at the same time.
childrentrueThe children to pass the location context to

Example: Animated Routes

import { LocationProvider, Location, Match } from "react-location";

const AnimatedWrapper = ({ children }) => (
  <Location>
    {location => (
      // Get the current location and its key
      // Use location.key as the unique ID in your animations
      <TransitionGroup className="transition-group">
        <CSSTransition key={location.key} classNames="fade" timeout={500}>
          {/* Manually pass LocationProvider the location prop for each animation */}
          <LocationProvider location={location} />
        </CSSTransition>
      </TransitionGroup>
    )}
  </Location>
);

render(
  <LocationProvider>
    <AnimatedWrapper>
      <MatchFirst>
        <Match path="/page/:pageID">
          {({ pageID, location }) => (
            <div
              className="page"
              style={{ background: `hsl(${pageID * 75}, 60%, 60%)` }}
            >
              {pageID}
            </div>
          )}
        </Match>
      </MatchFirst>
    </AnimatedWrapper>
  </LocationProvider>
);

Match

The Match component is used to render content when its path matches the current history's location. It is generally used for routing purposes. It also provides the new relative matching path to child Match components, allowing for clean nested route definition.

PropRequiredDescription
pathtrueThe path to match (relative to the nearest parent Match component or root basepath)
childrenThe content to be rendered when the path matches the current location
children()/render/componentThe function to be called when the path matches the current location. This function is called with the location API as the only paramter

Example

// Render children directly
render(<Match path="about">About me</Match>);

// Use children as a function
render(
  <Match path=":invoiceID">
    {location => <div>This is invoice #{location.params.invoiceID}</div>}
  </Match>
);

// Use a render function
render(
  <Match
    path=":invoiceID"
    render={location => <div>This is invoice #{location.params.invoiceID}</div>}
  />
);

// Use a component
const Invoice = ({ dark, location }) => (
  <div>This is invoice #{location.params.invoiceID}</div>
);

render(<Match path=":invoiceID" component={Invoice} dark />);

MatchFirst

The MatchFirst component is used to selectively render the first child component that is av valid match and/or provide fallbacks. This is useful for:

  • Nesting and Relative Routes
  • Matching index routes and hard-coded routes before dynamic ones
  • Default / fallback routes

Example - Route Params

render(
  <Match path="invoices">
    <MatchFirst>
      <Match path="/">This route would match and display at `/invoices/`</Match>
      <Match path="new">
        This route would match and display at `/invoices/new`
      </Match>
      <Match path=":invoiceID">
        {({ params }) => (
          <div>
            This route would match for all other `/invoices/:invoiceID/` routes
          </div>
        )}
      </Match>
    </MatchFirst>
  </Match>
);

Example - Default / Fallback Route

render(
  <MatchFirst>
    <Match path="/">This route would match and display at `/`</Match>
    <Match path="about">This route would match and display at `/about`</Match>
    <div>
      This element would be rendered as the fallback when no Matches are found
    </div>
  </MatchFirst>
);

Link

The Link component allows you to generate <a href/> links for navigation, capable of updating the:

  • Route path + hash
  • Query parameters
  • State
  • Push vs. Replace

The links generated by it are designed to work perfectly with Open in new Tab + ctrl + left-click and Open in new window.... They are also capable of receiving "active" props (depending on the activeType passed) to decorate the link when the link is currently active relative to the current location.

PropTypeDescription
...navigateAll properties for the navigate method are supported here.
activeTypestring (one of partial, path, hash or full)Defaults to full. Defines which matching strategy is used to determine if the link is active or not. See the table below for more information.
getActivePropsfunctionA function that is passed the Location API and returns additional props for the active state of this link. These props override other props passed to the link (style's are merged, className's are concatenated)

Example: The basics

render(
  <div>
    <Link to="/home">I will navigate to `/home`</Link>
    <Link to="todos">
      I will navigate to `./todos`, relative to the current location
    </Link>
    <Link to="..">I will navigate up one level in the location hierarchy.</Link>
    <Link to="#somehash">
      I will navigate to the hash `somehash` at the current location
    </Link>
    <Link to="/search?stringQuery=yes!">I will navigate to `/search?stringQuery=yes!`</Link>
    <Link
      query={
        someParams: true,
        otherParams: 'gogogo',
        object: { nested: { list: [1, 2, 3], hello: "world" } }
      }}
    >
      I will navigate to the current location + `?someParams=true&otherParams=gogogo&object=%7B%22nested%22%3A%7B%22list%22%3A%5B1%2C2%2C3%5D%2C%22hello%22%3A%22world%22%7D%7D`
    </Link>
    <Link
      query={query => ({
        ...query,
        addThis: 'This is new!',
        removeThis: undefined
      })}
    >
      I will add `addThis='This is new!' and also remove the `removeThis` param to/from the query params on the current page
    </Link>
  </div>
);

Example: Using getActiveProps

The following link will be green with /about as the current location.

<Link
  to="/about"
  getActiveProps={location => ({
    style: { color: "green" }
  })}
>
  About
</Link>

Using activeType

As mentioned above, activeType configures when a link is considered "active", and when getActiveProps() is run and applied to the link. Below is a table demonstrating the various options and how they behave:

TypeDescriptionExample

| full | hash

useLocation

Location

Redirect

createHistory

createMemorySource

Location API

Internnaly, there is only a single object, passed via context, that powers react-location. It contains both the current state and API for location and is the return result

navigate

PropTypeDescription
tostringThe path this link navigates to. It can be absolute, relative, external and can also contain a #hash. Defaults to the current location if not defined
queryobject/functionEither (1) the replacement query parameters for this link as an object, or (2) a function that receives the old query parameters and returns new ones
stateobject/functionEither (1) the replacement state for this link as an object, or (2) a function that receives the old state and returns new ones
replacebooleanWhether or not to replace the current history entry when this link is clicked
3.2.17

2 years ago

3.2.16

2 years ago

3.3.1

2 years ago

3.3.0

2 years ago

3.3.4

2 years ago

3.3.3

2 years ago

3.3.2

2 years ago

3.2.2

2 years ago

3.2.1

2 years ago

3.2.0

2 years ago

3.2.6

2 years ago

3.2.5

2 years ago

3.2.4

2 years ago

3.2.3

2 years ago

3.2.9

2 years ago

3.2.8

2 years ago

3.2.7

2 years ago

3.2.13

2 years ago

3.1.3

2 years ago

3.2.12

2 years ago

3.1.2

2 years ago

3.2.15

2 years ago

3.1.1

2 years ago

3.2.14

2 years ago

3.1.0

2 years ago

3.1.7

2 years ago

3.1.6

2 years ago

3.1.5

2 years ago

3.1.4

2 years ago

3.2.11

2 years ago

3.2.10

2 years ago

3.1.12

2 years ago

3.1.11

2 years ago

3.1.14

2 years ago

3.1.13

2 years ago

3.1.10

2 years ago

3.1.9

2 years ago

3.1.8

2 years ago

3.1.0-next.51

2 years ago

3.1.0-next.52

2 years ago

3.1.0-next.53

2 years ago

3.1.0-next.54

2 years ago

3.1.0-next.55

2 years ago

3.1.0-next.56

2 years ago

3.1.0-next.57

2 years ago

3.1.0-next.58

2 years ago

3.1.0-next.59

2 years ago

3.1.0-next.60

2 years ago

3.1.0-next.61

2 years ago

3.1.0-next.62

2 years ago

3.1.0-next.41

3 years ago

3.1.0-next.42

3 years ago

3.1.0-next.43

3 years ago

3.1.0-next.44

3 years ago

3.1.0-next.45

3 years ago

3.1.0-next.46

3 years ago

3.1.0-next.47

3 years ago

3.1.0-next.48

3 years ago

3.1.0-next.49

3 years ago

3.1.0-next.50

3 years ago

3.1.0-next.40

3 years ago

3.1.0-next.39

3 years ago

3.1.0-next.28

3 years ago

3.1.0-next.29

3 years ago

3.1.0-next.30

3 years ago

3.1.0-next.31

3 years ago

3.1.0-next.32

3 years ago

3.1.0-next.33

3 years ago

3.1.0-next.34

3 years ago

3.1.0-next.35

3 years ago

3.1.0-next.36

3 years ago

3.1.0-next.37

3 years ago

3.1.0-next.38

3 years ago

3.1.0-next.9

3 years ago

3.1.0-next.8

3 years ago

3.1.0-next.7

3 years ago

3.1.0-next.6

3 years ago

3.1.0-next.1

3 years ago

3.1.0-next.5

3 years ago

3.1.0-next.4

3 years ago

3.1.0-next.3

3 years ago

3.1.0-next.2

3 years ago

3.1.0-next.10

3 years ago

3.1.0-next.11

3 years ago

3.1.0-next.12

3 years ago

3.1.0-next.13

3 years ago

3.1.0-next.16

3 years ago

3.1.0-next.18

3 years ago

3.1.0-next.19

3 years ago

3.1.0-next.20

3 years ago

3.1.0-next.21

3 years ago

3.1.0-next.22

3 years ago

3.1.0-next.23

3 years ago

3.1.0-next.24

3 years ago

3.1.0-next.25

3 years ago

3.1.0-next.26

3 years ago

3.1.0-next.27

3 years ago

0.0.1-next.0

3 years ago

3.0.2

3 years ago

3.0.1

3 years ago

3.0.0

3 years ago

2.0.8

4 years ago

2.0.7

5 years ago

2.0.6

5 years ago

2.0.5

5 years ago

2.0.4

5 years ago

2.0.3

5 years ago

2.0.2

5 years ago

2.0.1

5 years ago

2.0.0

5 years ago

1.1.2

5 years ago

1.1.1

5 years ago

1.1.0

5 years ago

1.0.9

5 years ago

1.0.8

5 years ago

1.0.7

5 years ago

1.0.6

5 years ago

1.0.5

5 years ago

1.0.4

5 years ago

1.0.3

5 years ago

1.0.2

5 years ago

1.0.1

5 years ago

1.0.0

5 years ago

1.0.0-beta.2

5 years ago

1.0.0-beta.1

5 years ago

1.0.0-beta.0

5 years ago

0.2.2

9 years ago