use-http: Trigger new request on url change

Currently I can’t figure out a short and simple way to fetch data onMount and when the url changes.

The code below only triggers on mount, and looking at the docs (and source code) it doesn’t seem like useGet takes a dependency array (like useEffect does) that indicates when the effect should execute again, is there some other option to get it re-run on url change as well as mount? Am I missing some other trivial way of accomplishing this?

import {useGet} from 'use-http'

function Todos(props) {
  const options = {
    onMount: true // will fire on componentDidMount
  }

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

  return (
    <>
      {request.error && 'Error!'}
      {request.loading && 'Loading...'}
      {(todos.data || []).length > 0 && todos.data.map(todo => (
        <div key={todo.id}>{todo.title}</div>
      )}
    </>
  )
}

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 27

Most upvoted comments

Sorry, I’ve been quite swamped at work so I haven’t had the time to look at the example you posted and really think about it, but I looked at the PR now and I’d just like to say that I agree with your final decision 😃

Okay, I added onUpdate. It’s available in v0.1.83. It’s possible in the future we change this to a better name, but for now this works and should do exactly what you’re looking for. 😊Going to close this. Feel free to reopen if something doesn’t work or if you have some more syntax ideas!

@Markus-ipse this feature for the onMount loading === true by default is implemented in this branch and all the tests are working. Will merge today

I should be able to hop back on this, this week.

For this, I think there are times that you don’t want loading to be set to true by default. If you want to submit a form, you don’t want loading true by default, only when you click submit. But, if this is the desired thing, then we could add something like:

<Provider url='' options={{ initialLoading: true }}><App /></Provider>

Isn’t it enough to check if onMount === true and/or it’s a GET request?

So I think eventually I’m going to be deprecating the onMount feature. The best way to accomplish this is

import useFetch from 'use-http'

function Todos({ someID }) {
  const { get, data, loading, error } = useFetch('https://example.com/todos')

  useEffect(() => { // this should fire onMount and when someID changes
    get(`/${someID}`)
  }, [someID, get])

  return (
    <>
      {error && 'Error!'}
      {loading && 'Loading...'}
      {(data || []).length > 0 && data.map(todo => (
        <div key={todo.id}>{todo.title}</div>
      )}
    </>
  )
}

Alternatively this might work if someID isn’t coming from a url change

import useFetch from 'use-http'
import useRouter from 'use-react-router'

function Todos({ someID }) {
  const { get, data, loading, error } = useFetch('https://example.com/todos')
  const { location } = useRouter()

  useEffect(() => { // this should fire onMount and when location.pathname changes
    get(`/${someID}`)
  }, [location.pathname, get])

  return (
    <>
      {error && 'Error!'}
      {loading && 'Loading...'}
      {(data || []).length > 0 && data.map(todo => (
        <div key={todo.id}>{todo.title}</div>
      )}
    </>
  )
}