New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

use-http

Package Overview
Dependencies
Maintainers
1
Versions
102
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

use-http

```jsx import { useQuery } from 'use-http'

  • 0.1.78
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
17K
decreased by-11.23%
Maintainers
1
Weekly downloads
 
Created
Source

useFetch


undefined

🐶 React hook for making isomorphic http requests
Main Documentation


npm i use-http


Features

  • SSR (server side rendering) support
  • TypeScript support
  • 1 dependency (use-ssr)
  • GraphQL support (queries + mutations)
  • Provider to set default url and options

Usage

⚠️ Examples click me
Basic Usage useFetch
import useFetch from 'use-http'

function Todos() {
  const options = { // accepts all `fetch` options
    onMount: true // will fire on componentDidMount
  }

  const todos = useFetch('https://example.com/todos', options)

  function addTodo() {
    todos.post({
      title: 'no way',
    })
  }

  return (
    <>
      <button onClick={addTodo}>Add Todo</button>
      {request.error && 'Error!'}
      {request.loading && 'Loading...'}
      {(todos.data || []).length > 0 && todos.data.map(todo => (
        <div key={todo.id}>{todo.title}</div>
      )}
    </>
  )
}
Destructured useFetch
var [data, loading, error, request] = useFetch('https://example.com')

// want to use object destructuring? You can do that too
var { data, loading, error, request } = useFetch('https://example.com')
Relative routes useFetch

⚠️ baseUrl is no longer supported, it is now only url

var request = useFetch({ url: 'https://example.com' })
// OR
var request = useFetch('https://example.com')

request.post('/todos', {
  no: 'way'
})
useGet, usePost, usePatch, usePut, useDelete
import { useGet, usePost, usePatch, usePut, useDelete } from 'use-http'

const [data, loading, error, patch] = usePatch({
  url: 'https://example.com',
  headers: {
    'Accept': 'application/json; charset=UTF-8'
  }
})

patch({
  yes: 'way',
})
Abort useFetch
const githubRepos = useFetch({
  url: `https://api.github.com/search/repositories?q=`
})

// the line below is not isomorphic, but for simplicity we're using the browsers `encodeURI`
const searchGithubRepos = e => githubRepos.get(encodeURI(e.target.value))

<>
  <input onChange={searchGithubRepos} />
  <button onClick={githubRepos.abort}>Abort</button>
  {githubRepos.loading ? 'Loading...' : githubRepos.data.items.map(repo => (
    <div key={repo.id}>{repo.name}</div>
  ))}
</>
GraphQL Query useFetch

const QUERY = `
  query Todos($userID string!) {
    todos(userID: $userID) {
      id
      title
    }
  }
`

function App() {
  const request = useFetch('http://example.com')

  const getTodosForUser = id => request.query(QUERY, { userID: id })

  return (
    <>
      <button onClick={() => getTodosForUser('theUsersID')}>Get User's Todos</button>
      {request.loading ? 'Loading...' : <pre>{request.data}</pre>}
    </>
  )
}
GraphQL Mutation useFetch

The Provider allows us to set a default url, options (such as headers) and so on.


const MUTATION = `
  mutation CreateTodo($todoTitle string) {
    todo(title: $todoTitle) {
      id
      title
    }
  }
`

function App() {
  const [todoTitle, setTodoTitle] = useState('')
  const request = useFetch('http://example.com')

  const createtodo = () => request.mutate(MUTATION, { todoTitle })

  return (
    <>
      <input onChange={e => setTodoTitle(e.target.value)} />
      <button onClick={createTodo}>Create Todo</button>
      {request.loading ? 'Loading...' : <pre>{request.data}</pre>}
    </>
  )
}
Provider using the GraphQL useMutation and useQuery
Query for todos
import { useQuery } from 'use-http'

export default function QueryComponent() {
  
  // can also do it this way:
  // const [data, loading, error, query] = useQuery`
  // or this way:
  // const { data, loading, error, query } = useQuery`
  const request = useQuery`
    query Todos($userID string!) {
      todos(userID: $userID) {
        id
        title
      }
    }
  `

  const getTodosForUser = id => request.query({ userID: id })
  
  return (
    <>
      <button onClick={() => getTodosForUser('theUsersID')}>Get User's Todos</button>
      {request.loading ? 'Loading...' : <pre>{request.data}</pre>}
    </>
  )
}
Add a new todo
import { useMutation } from 'use-http'

export default function MutationComponent() {
  const [todoTitle, setTodoTitle] = useState('')
  
  // can also do it this way:
  // const request = useMutation`
  // or this way:
  // const { data, loading, error, mutate } = useMutation`
  const [data, loading, error, mutate] = useMutation`
    mutation CreateTodo($todoTitle string) {
      todo(title: $todoTitle) {
        id
        title
      }
    }
  `
  
  const createTodo = () => mutate({ todoTitle })

  return (
    <>
      <input onChange={e => setTodoTitle(e.target.value)} />
      <button onClick={createTodo}>Create Todo</button>
      {loading ? 'Loading...' : <pre>{data}</pre>}
    </>
  )
}
Adding the Provider

These props are defaults used in every request inside the <Provider />. They can be overwritten individually

import { Provider } from 'use-http'
import QueryComponent from './QueryComponent'
import MutationComponent from './MutationComponent'

function App() {

  const options = {
    headers: {
      Authorization: 'Bearer:asdfasdfasdfasdfasdafd'
    }
  }
  
  return (
    <Provider url='http://example.com' options={options}>
      <QueryComponent />
      <MutationComponent />
    <Provider/>
  )
}

Overview

Hooks
HookDescription
useFetchThe base hook
useGetDefaults to a GET request
usePostDefaults to a POST request
usePutDefaults to a PUT request
usePatchDefaults to a PATCH request
useDeleteDefaults to a DELETE request
useQueryFor making a GraphQL query
useMutationFor making a GraphQL mutation
Options

This is exactly what you would pass to the normal js fetch, with a little extra.

OptionDescriptionDefault
onMountOnce the component mounts, the http request will run immediatelyfalse
urlAllows you to set a base path so relative paths can be used for each request :)empty string
const {
  data,
  loading,
  error,
  request,
  get,
  post,
  patch,
  put,
  delete  // don't destructure `delete` though, it's a keyword
  del,    // <- that's why we have this (del). or use `request.delete`
  abort,
  query,  // GraphQL
  mutate, // GraphQL
} = useFetch({
  // accepts all `fetch` options such as headers, method, etc.
  url: 'https://example.com', // used to be `baseUrl`
  onMount: true
})

or

const [data, loading, error, request] = useFetch({
  // accepts all `fetch` options such as headers, method, etc.
  url: 'https://example.com', // used to be `baseUrl`
  onMount: true
})

const {
  get,
  post,
  patch,
  put,
  delete  // don't destructure `delete` though, it's a keyword
  del,    // <- that's why we have this (del). or use `request.delete`
  abort,
  query,  // GraphQL
  mutate, // GraphQL
} = request

Feature Requests/Ideas

If you have feature requests, let's talk about them in this issue!

Todos

  • tests
    • tests for SSR
    • tests for FormData (can also do it for react-native at same time. see here)
    • tests for GraphQL hooks useMutation + useQuery
  • make work with FormData
  • Make work with React Suspense current example WIP
  • get it all working on a SSR codesandbox, this way we can have api to call locally
  • Allow option to fetch on server instead of just having loading state
  • add timeout
  • add debounce
  • maybe add a retry: 3 which would specify the amount of times it should retry before erroring out
  • ERROR handling:
    • make sure options (as 2nd param) to all hooks except useMutation and useQuery is an object, if not invariant/throw error
  • add array destructuring return types for helper hooks
  • make GraphQL work with React Suspense
  • make GraphQL examples in codesandbox
  • Documentation:
    • add preview image
    • add google analytics
    • show comparison with Apollo
  • maybe add syntax for inline headers like this
  const user = useFetch()
  
  user
    .headers({
      auth: jwt
    })
    .get()

The Goal With Suspense (not implemented yet)
import React, { Suspense, unstable_ConcurrentMode as ConcurrentMode, useEffect } from 'react'

function WithSuspense() {
  const suspense = useFetch('https://example.com')

  useEffect(() => {
    suspense.read()
  }, [])

  if (!suspense.data) return null

  return <pre>{suspense.data}</pre>
}

function App() (
  <ConcurrentMode>
    <Suspense fallback="Loading...">
      <WithSuspense />
    </Suspense>
  </ConcurrentMode>
)
GraphQL with Suspense (not implemented yet)
const App = () => {
  const [todoTitle, setTodoTitle] = useState('')
  // if there's no <Provider /> used, useMutation works this way
  const mutation = useMutation('http://example.com', `
    mutation CreateTodo($todoTitle string) {
      todo(title: $todoTitle) {
        id
        title
      }
    }
  `)

  // ideally, I think it should be mutation.write({ todoTitle }) since mutation ~= POST
  const createTodo = () => mutation.read({ todoTitle })
  
  if (!request.data) return null

  return (
    <>
      <input onChange={e => setTodoTitle(e.target.value)} />
      <button onClick={createTodo}>Create Todo</button>
      <pre>{mutation.data}</pre>
    </>
  )
}

Keywords

FAQs

Package last updated on 18 Jul 2019

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc