• This repository has been archived on 03/Aug/2023
  • Stars
    star
    362
  • Rank 117,671 (Top 3 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created almost 7 years ago
  • Updated almost 4 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Declarative HTTP requests for React

React Request

Travis build status npm version Test Coverage gzip size

Declarative HTTP requests for React.

Motivation

Making a single HTTP request is not difficult to do in JavaScript. However, complex web applications often make many requests as the user navigates through the app.

Features such as request deduplication and response caching can often save the developer of apps like these from headache and bugs. Although it is possible to implement these features imperatively, it requires that you write a bit of code, and that code can be tedious to test.

A declarative API makes things a lot simpler for you, which is where React Request comes in. React Request is a backend-agnostic, declarative solution for HTTP requests in React, and its deduping and caching features are a delight to use.

Features

βœ“ Uses the native fetch API
βœ“ Smart deduping of requests
βœ“ Customizable response caching
βœ“ Integrates with external stores (such as Redux)
βœ“ Reasonable footprint (~2kb gzipped)

Installation

Install using npm:

npm install react-request

or yarn:

yarn add react-request

Documentation

Getting Started

Here's a quick look at what using React Request is like:

import React, { Component } from 'react';
import { Fetch } from 'react-request';

class App extends Component {
  render() {
    return (
      <Fetch url="https://jsonplaceholder.typicode.com/posts/1">
        {({ fetching, failed, data }) => {
          if (fetching) {
            return <div>Loading data...</div>;
          }

          if (failed) {
            return <div>The request did not succeed.</div>;
          }

          if (data) {
            return (
              <div>
                <div>Post ID: {data.id}</div>
                <div>Post Title: {data.title}</div>
              </div>
            );
          }

          return null;
        }}
      </Fetch>
    );
  }
}

Need to make multiple requests? You can use any tool that you would like that allows you to "compose" render prop components together. This example uses React Composer:

import React, { Component } from 'react';
import Composer from 'react-composer';

class App extends Component {
  render() {
    return (
      <Composer
        components={[
          <Fetch url="https://jsonplaceholder.typicode.com/posts/1" />,
          <Fetch
            url="https://jsonplaceholder.typicode.com/posts/1"
            method="DELETE"
          />,
        ]}>
        {([readPost, deletePost]) => {
          return (
            <div>
              {readPost.fetching && 'Loading post 1'}
              {!readPost.fetching && 'Post 1 is not being fetched'}
              <button onClick={() => deletePost.doFetch()}>
                Delete Post 1
              </button>
            </div>
          );
        }}
      </Composer>
    );
  }
}

These examples just scratch the surface of what React Request can do for you. Check out the API reference below, or read the guides, to learn more.

API

<Fetch />

A component for making a single HTTP request. This is the export from this library that you will use most frequently.

import { Fetch } from 'react-request';
Props

The <Fetch/> components accepts every value of init and input from the fetch() API as a prop, in addition to a few other things.

The complete list of props is:

Prop Default value Description
url From fetch(). The URL to send the request to
method 'GET' From fetch(). The HTTP method to use
body From fetch(). The request body to send along with the request
credentials From fetch(). The request credentials you want to use for the request: omit, same-origin, or include.
headers From fetch(). Headers to send along with the request
children A function that is called with a single argument containing information about the request. Learn more.
lazy Varies Whether or not the request is made when the component mounts.
beforeFetch A function called before a network request is made.
afterFetch A function that is only called after a network request is made.
onResponse A function called anytime a response is received, whether from the network or cache.
transformData A function that is called with the body of the response, allowing you to transform it.
responseType 'json' Whether or not the request is made when the component mounts.
requestName A name to give this request, which can be useful for debugging.
fetchPolicy The cache strategy to use.
cacheResponse Varies Whether or not to cache the response for this request.
dedupe true Whether or not to dedupe this request.
requestKey Generated A key that is used for deduplication and response caching.
mode From fetch(). The mode you want to use for the request
cache From fetch(). The browser's cache mode you want to use for the request
redirect From fetch(). The redirect mode to use
referrer 'about:client' From fetch(). The referrer to use for the request
referrerPolicy '' From fetch(). Specifies the value of the referer HTTP header.
integrity '' From fetch(). Contains the subresource integrity value of the request
keepalive From fetch(). Can be used to allow the request to outlive the page
signal From fetch(). An AbortSignal object instance

To learn more about the valid options for the props that come from fetch, refer to the fetch() documentation.

The following example demonstrates some of the most commonly-used props that come from fetch():

<Fetch
  url="/posts/2"
  method="patch"
  credentials="same-origin"
  headers={{
    'csrf-token': myCsrfToken,
  }}
  body={JSON.stringify({ title: 'New post' })}>
  {({ doFetch }) => {
    <button onClick={() => doFetch()}>Update Post</button>;
  }}
</Fetch>

In addition to the fetch() props, there are a number of other useful props.

props.children

children is the render prop of this component. It is called with one argument, result, an object with the following keys:

Key Type Description
fetching Boolean A Boolean representing whether or not a request is currently in flight for this component
failed Boolean A Boolean representing whether or not the request failed for any reason. This includes network errors and status codes that are greater than or equal to400.
error Object An error object representing a network error occurred. Note that HTTP "error" status codes do not cause errors; only failed or aborted network requests do. For more, see the "Using Fetch" MDN guide.
response Object An instance of Response. The body will already be read, and made available to you as response.data.
data Object The data returned in response. This will be different from response.data if a transformData prop was passed to <Fetch/>.
doFetch Function A function that allows you to manually make the HTTP request. Read more.
url String The URL that was passed as a prop to <Fetch />
requestName String The name of the request (see requestName below)
requestKey String The request key of the request
Using doFetch

There are three common use cases for the doFetch prop:

  • You can use it to "refresh" the data by making a follow-up request for read requests
  • You can use it to retry the request if there is any sort of error
  • You must manually call this method to actually make the request anytime that the lazy prop is passed as true.

doFetch accepts one argument: options. Any of the fetch() options, such as url, method, and body are valid options. You may also specify a new requestKey if you are manually generating your own keys. This method allows you to customize the request from within the component based on the component's state.

doFetch returns a Promise that always resolves. It resolves to the same argument that the afterFetch prop receives.

In the following example, we demonstrate how you can modify the request by passing options to doFetch.

<Fetch {...props}>
  {({ doFetch }) => (
    // You can pass options to `doFetch` to customize the request. All of the props from `fetch()`, such as `url`,
    // `body`, and so on, are supported.
    <button onClick={() => doFetch({ body: this.getResponseBody() })}>
      Perform Action
    </button>
  )}
</Fetch>
props.lazy

Whether or not the request will be called when the component mounts. The default value is based on the request method that you use.

Method Default value
GET, HEAD, OPTIONS false
POST, PUT, PATCH, DELETE true
<Fetch url="/books" lazy>
  {({ doFetch }) => {
    <button onClick={() => doFetch()}>Load the books</button>;
  }}
</Fetch>
props.beforeFetch

A function that is called just before a network request is initiated. It is called with one argument, an object with the following keys:

  • url: The URL of the request
  • init: The second argument passed to global.fetch(), which specifies things such as the body, method, and so on
  • requestKey: Either the computed request key, or the value of the requestKey prop

This feature is useful for analytics, or syncing response data with a data store such as Redux.

Note: This function is not called when the component reads from the cache.

props.afterFetch

A function that is called anytime that a network response is received. It is called with one argument, an object with the following keys:

  • url: The URL of the request
  • init: The second argument passed to global.fetch(), which specifies things such as the body, method, and so on
  • requestKey: Either the computed request key, or the value of the requestKey prop
  • response: The response that was received from the HTTP request
  • data: The transformed data from the response. This will be different from response.data if a transformData function was passed as a prop to <Fetch/>.
  • error: An error returned from the HTTP request
  • didUnmount: A Boolean representing whether or not the component has unmounted

This can be used for analytics or syncing response data with a data store such as Redux.

Note: This function is not called when the component reads from the cache.

props.onResponse

A function that is called every time a response is received, whether that response is from the cache or from a network request. Receives two arguments: error and response.

<Fetch
  url="/posts/2"
  onResponse={(error, response) => {
    if (error) {
      console.log('Ruh roh', error);
    } else {
      console.log('Got a response!', response);
    }
  }}>
  {() => {
    <div>Hello</div>;
  }}
</Fetch>
props.transformData

A function that is called with the data returned from the response. You can use this hook to transform the data before it is passed into children.

<Fetch
  url="/posts/2"
  transformData={data => data.post>
  {({ fetching, error, response, data }) => {
    <div>
      {fetching && ('Loading...')}
      {error && ('There was an error.')}
      {!fetching && !error && response.status === 200 && (
        <div>
          <h1>{data.title}</h1>
          <div>{data.content}</div>
        </div>
      )}
    </div>
  }}
</Fetch>

Note: transformData does not modify the value of response.data. The transformed data is made available to you in the render prop argument under the data key.

props.responseType

The content type of the response body. Defaults to "json" unless the response has a 204 status code, in which case it will be "text" instead. Valid values are any of the methods on Body.

Alternatively, you may specify a function that returns a string. The function will be called with one argument: response. This allows you to dynamically specify the response type based on information about the response, such as its status code.

// If you have an endpoint that just returns raw text, you could, for instance, convert it into
// an object using `responseType` and `transformData`.
<Fetch
  url="/countries/2"
  responseType="text"
  transformData={countryName => {
    return {
      countryName,
    };
  }}>
  {({ data }) => {
    if (data) {
      return <div>{data.countryName}</div>;
    }

    return null;
  }}
</Fetch>

If the response body cannot be parsed as the responseType that you specify, then data will be set to null.

props.requestName

A name to give this request, which can help with debugging purposes. The request name is analogous to a function name in JavaScript. Although we could use anonymous functions everywhere, we tend to give them names to help humans read and debug the code.

<Fetch url={`/posts/${postId}`} requestName="readPost" />

Note: This feature is analogous to the operation name in GraphQL.

props.fetchPolicy

This determines how the request interacts with the cache. Valid options are:

  • "cache-first"
  • "cache-and-network"
  • "network-only"
  • "cache-only"

For documentation on what each of these values do, refer to the response caching guide.

The default value of this prop is based on the value of the method prop that you pass to <Fetch/>.

Method Default value
GET, HEAD, OPTIONS "cache-first"
POST, PUT, PATCH, DELETE "network-only"

This prop behaves identically to the Apollo prop with the same name.

props.cacheResponse

Whether or not the response will be cached. The default value is based on the value of the method prop that you pass to <Fetch/>.

Method Default value
GET, HEAD, OPTIONS true
POST, PUT, PATCH, DELETE false

For documentation on this prop, refer to the response caching guide.

props.dedupe

A Boolean value representing whether or not the request should be deduplicated. Defaults to true.

props.requestKey

A string that is used to control the request deduplication and response caching features. By default, a key is generated for you. Specifying a custom key is an advanced feature that you may not need.

For more, see the request key guide.


The rest of the API documentation describes the other named exports from the react-request package. Typically, you won't need to use these, but they are available should you need them.

fetchDedupe( input [, init] [, dedupeOptions] )

This is the fetchDedupe export from the Fetch Dedupe library. Fetch Dedupe powers the request deduplication in React Request.

Whenever you need to make a standalone HTTP request outside of the <Fetch /> component, then you can use this with confidence that you won't send a duplicate request.

For more, refer to the documentation of fetch-dedupe.

getRequestKey({ url, method, body, responseType })

Generates a request key. All of the values are optional. You typically never need to use this, as request keys are generated automatically for you when you use React Request or Fetch Dedupe.

This method comes from fetch-dedupe.

isRequestInFlight( requestKey )

Return a Boolean representing if a request for requestKey is in flight or not.

This method comes from fetch-dedupe.

clearRequestCache()

Wipes the cache of deduped requests. Mostly useful for testing.

This method comes from fetch-dedupe.

Note: this method is not safe to use in application code.

clearResponseCache()

Wipes the cache of cached responses. Mostly useful for testing.

Note: this method is not safe to use in application code.

Acknowledgements

This library was inspired by Apollo. The library Holen was referenced during the creation of this library.

More Repositories

1

react-composer

Compose render prop components
JavaScript
611
star
2

redux-resource

3kb resource management for Redux
JavaScript
237
star
3

moment-business

Utilities for work days in Moment. (Western workweeks only.)
JavaScript
99
star
4

gistbook

[No longer hosted] A place to write about technical subjects on the web.
JavaScript
89
star
5

marionette.transition-region

(Unsupported) Because animated view transitions should be easy.
JavaScript
52
star
6

backbone.base-router

A better starting point for building a new Backbone Router.
JavaScript
49
star
7

testing-with-babel

[Don't reference this]: Examples of using Babel with popular testing tools
48
star
8

react-state-context

Lightweight state management using React Context
JavaScript
45
star
9

bestfetch

fetch ⭐️caching ⭐️deduplication
JavaScript
44
star
10

backbone.intercept

Ambient management of link clicks and form submissions.
JavaScript
44
star
11

lrud

A React library for managing focus in TV apps.
TypeScript
40
star
12

router-comparison

WIP: A comparison of client side routers.
38
star
13

knockout-view

(No longer maintained) A bookmarklet that toggles a display of any page's Knockout View Model.
JavaScript
33
star
14

moolah-old

The source code for the original version of Moolah
JavaScript
32
star
15

es6-node-boilerplate

A boilerplate to author, then transpile, Node libraries in ES6.
JavaScript
23
star
16

zero-boilerplate-redux

An example real-world Redux CRUD application with no boilerplate
JavaScript
18
star
17

materialish

React components that loosely follow Material Design
JavaScript
17
star
18

marionette.sliding-view

A sliding Collection View in Marionette.
JavaScript
16
star
19

material-design-icons

A repository for Material Design SVG Icons
HTML
13
star
20

prevent-scroll

[unmaintained] Reliably disable scrolling
JavaScript
12
star
21

simple-jsdom

A simple JSDom configuration for testing libraries.
JavaScript
12
star
22

hsm.js

A minimal hierarchal state machine for Javascript.
JavaScript
12
star
23

query-history

A history with improved query parameter support
TypeScript
12
star
24

bizniz.js

Constant-time business utilities for the western work week
JavaScript
11
star
25

fade-dropdown-menu

A dropdown menu with a fade.
CSS
11
star
26

redux-simple-resource

Project moved --->
JavaScript
11
star
27

latex-to-unicode.js

Convert LaTeX strings to unicode.
JavaScript
10
star
28

standard-resource

WIP: A normalized data store
JavaScript
10
star
29

timeline-utils

WIP: Utilities for working with timeline visualizations
TypeScript
10
star
30

api-pls

Need a backend? Just say please
JavaScript
10
star
31

surfaces.js

Visualize multivariable functions in the browser.
JavaScript
9
star
32

core-hooks

A (small) collection of useful React hooks
TypeScript
9
star
33

backbone.event-spec

An unofficial specification for Backbone Event names.
9
star
34

backbone.simple-auth

A basic cookie-based client-side auth service for Backbone apps.
JavaScript
9
star
35

little-marionette-guides

Short, opinionated guides on some Marionette concepts.
8
star
36

pwa-notes

Notes on building native-feeling Progressive Web Apps
8
star
37

unicode-math.js

Unicode values for math symbols.
JavaScript
7
star
38

backbone.premium-router

(WIP) A premium routing solution for Backbone.
JavaScript
7
star
39

backbone-architecture-101

A short, opinionated guide to Backbone architecture.
7
star
40

moolah-calculators

Calculators for personal finance
JavaScript
7
star
41

react-ui-reference

Reference UI patterns implemented in React
JavaScript
7
star
42

responsive-stylus-mixins

Responsive mixins for Stylus
CSS
7
star
43

react-app-guidelines

Tips that I use when building new React apps
6
star
44

unicode-escape.js

Convert a unicode string to a string of Javascript escape sequences.
JavaScript
6
star
45

backbone.class-event-spec

(WIP) A specification for handling important events in Backbone Classes.
5
star
46

focus

A React library for managing focus in TV apps
JavaScript
5
star
47

cycle-connection-driver

A Cycle.js driver for connection status
JavaScript
5
star
48

stock-market-data

U.S. Stock Market data from Robert Shiller
JavaScript
4
star
49

dom-op-tester

Test DOM ops that may cause reflows with MutationObserver
JavaScript
4
star
50

puppets

A modern Backbone extension.
4
star
51

backbone.overlay-view

A view that covers the app and emits click events.
JavaScript
4
star
52

tangible.js

Create living DOM representations of Javascript objects.
JavaScript
4
star
53

react-media-ui

TypeScript
4
star
54

sliding-dropdown

A simple sliding menu.
CSS
4
star
55

marionette.base-view

A better View for Marionette.
JavaScript
4
star
56

vscode-new-files-from-template

Create VSCode files from a template definition
JavaScript
3
star
57

quantize-number

Quantize a number
JavaScript
3
star
58

i18n-list-generator.js

Generate localized lists
JavaScript
3
star
59

api-pls-example

An api-pls example project
3
star
60

cal

A scheduling app.
JavaScript
2
star
61

example-ts-lib

Example TypeScript library
JavaScript
2
star
62

backbone-orbit

An integration of Backbone and Orbit.js
2
star
63

react-over

Coming soon. A library for positioning elements that appear over the rest of your application
JavaScript
2
star
64

heartbeat.js

Execute a function on an interval
JavaScript
2
star
65

katex-symbols

View all of the symbols that KaTeX supports.
JavaScript
2
star
66

advanced-passport-example

An example application using Passport + social logins, with Postgres for sessions.
JavaScript
2
star
67

pleaserc

Linting configuration for ESLint.
2
star
68

simple-segment-aggregation.js

Aggregate consecutive segments by their events.
JavaScript
2
star
69

two-rotations.js

Rotate vectors about two axes.
JavaScript
2
star
70

js-playground

Just playing around with future JavaScript features...
JavaScript
2
star
71

nearest-periodic-value.js

Find the nearest value of a discrete periodic function, given a point.
JavaScript
2
star
72

jmeas-table-of-contents

[deprecated] see https://github.com/jamesplease/jmeas.com
JavaScript
2
star
73

emoji-clock

An emoji clock web component
JavaScript
2
star
74

backbone.routing-v2

A prototype implementation of Backbone v2 routing and history.
JavaScript
2
star
75

doc-components

React components for documentation sites
CSS
1
star
76

babel-module-inconsistency

This demonstrates the behavior of the es2015 modules=>CJS transform for Babel
JavaScript
1
star
77

cra-template-please

My personal Create React App template
CSS
1
star
78

yearly-to-monthly

Convert yearly values (like salary) to their monthly equivalent
JavaScript
1
star
79

sourcemap-options

The future source map options for the entire grunt-contrib suite
1
star
80

admiral-ui

1
star
81

use-mount-animation

A React Hook for mount and unmount animations
1
star
82

orbit-examples

Examples showing common use cases for Orbit.js
1
star
83

namespace-diff.js

Generate the diff between two namespaces.
JavaScript
1
star
84

katex-support.js

Generate lists of the functions and symbols that KaTeX supports.
JavaScript
1
star
85

desert-racer

A 2D puzzle game written in Unity
C#
1
star
86

moolah-lib

Utilities for finance applications.
TypeScript
1
star
87

react-redux-resource

React bindings for Redux Resource
JavaScript
1
star
88

add-skipping-holes.js

Add values while skipping periodic holes
1
star
89

time-segments.js

Group event data into segments of time.
JavaScript
1
star
90

resource-experiments

Development respository for new resource API
JavaScript
1
star
91

fi-calc-guide

The guide book for FI Calc
JavaScript
1
star
92

simple-css

A straightforward way to write organized & scaleable CSS
1
star
93

moolah

1
star
94

underscore-medley

An assortment of Underscore mixins
JavaScript
1
star
95

simulation-engine

A backtesting and Monte Carlo simulation engine
1
star
96

vscode-snippets

My VSCode snippets
1
star
97

latex-symbols-list.js

A list of LaTeX + AMS symbols.
JavaScript
1
star
98

react-fetcher-app

Development repository for react-fetcher
JavaScript
1
star
99

contained-periodic-values.js

Find how many values of a discrete periodic function are contained in an interval.
JavaScript
1
star
100

consecutive-segments.js

Group consecutive segments.
JavaScript
1
star