Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UseSWR wrapper doesnt override and routes to the wrong fetcher (SWR global config's) #2155

Closed
ridhwaans opened this issue Sep 11, 2022 · 2 comments · May be fixed by #2245
Closed

UseSWR wrapper doesnt override and routes to the wrong fetcher (SWR global config's) #2155

ridhwaans opened this issue Sep 11, 2022 · 2 comments · May be fixed by #2245

Comments

@ridhwaans
Copy link

ridhwaans commented Sep 11, 2022

Bug report

Description / Observed Behavior

As the title says, I have a useSharedState hook that is used to pass state between components without prop drilling. This hook is not for http resources, it doesnt have a url fetcher but has an initial state option

import useSWR from 'swr'

export const useSharedState = (key, initial) => {
  const { data: state, mutate: setState } = useSWR(key, null, {
    fallbackData: initial,
  })

  return [state, setState]
}

I also have SWR global config in my App.js with its own fetcher

import useSWR, { SWRConfig } from 'swr'

const App = () => {

    return (
        <React.Fragment>
            <SWRConfig
                value={{
                    fetcher: (resource, init) => fetch(`${process.env.REACT_APP_BASE_URL}/api` + resource, init).then(res => res.json())
                }}
            >
                <BrowserRouter basename={process.env.PUBLIC_URL}>
                    <Routes>
                    ...

When I make an useSWR call it adds the base url to query endpoints in components

However when I have useSWR and useSharedState in the same component or when I call useSharedState directly, it goes to the wrong fetcher & url endpoint defined thats in SWRConfig

import useSWR from 'swr'
import { useSharedState } from "../../hooks/useSharedState"
...
function Books() {
    
    useEffect(() => {
        document.documentElement.className = "inset";
        document.body.className = "inset-body"; 
    }, [])

    const {data : recentlyAddedBooks } = useSWR('/books/recently_added');
    const [searchInput, setSearchInput] = useSharedState('searchInput') // used for getting text from a searchbox
    
    return (...)

it returns

`GET http://localhost:5000/apisearchInput 404 (Not Found)` because its not a resource url

Expected Behavior

Need all SWR calls with resource urls i.e. useSWR('/books') to follow the global fetcher in <SWRConfig/> but other SWR wrappers like useSharedState() that is not meant for API calls should not use global fetcher option

What am I doing wrong, do I need to fix the hook param to override fetcher?

Repro Steps / Code Example

Additional Context

swr version "^1.3.0",

@koba04
Copy link
Collaborator

koba04 commented Sep 12, 2022

@ridhwaans
Thank you for reporting this.
A workaround for this is to pass fetcher: null to the useSWR in useSharedState. This avoids overriding useSWR's fetcher function by the global fetcher option.

import useSWR from 'swr'

export const useSharedState = (key, initial) => {
  const { data: state, mutate: setState } = useSWR(key, null, {
    fallbackData: initial,
    fetcher: null
  })

  return [state, setState]
}

It might be better to provide a better way for this if we'd like to push out this pattern.

@Dragate
Copy link

Dragate commented Sep 12, 2022

A workaround for this is to pass fetcher: null to the useSWR.

I have the exact same issue as OP. I was trying to find workarounds myself, such as providing a noop operation () => {} to the second argument of useSWR or evaluate permanently to true for isPaused option. Some (sort of) worked but no solution I came up with was clean. Thank you for your workaround (although it is a bit verbose and not TS-friendly).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants