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

How to use useSwr when I was clicking on a save button to update something? #254

Closed
loveholly opened this issue Feb 9, 2020 · 14 comments
Closed

Comments

@loveholly
Copy link

No description provided.

@sergiodxa
Copy link
Contributor

Do you mean not start the fetching until you click a button? If that's your use case you can pass null as the key of useSWR and then change it to the URL.

function FetchOnClick() {
  const [shouldFetch, setShouldFetch] = React.useState(false);
  const { data } = useSWR(shouldFetch ? null : "/api/users/1", fetcher);
  function handleClick() {
    setShouldFetch(true);
  }
  return (
    <>
      <button disable={shouldFetch} onClick={handleClick}>Fetch</button>
      {data ? <h1>{data.fullName}</h1> : null}
    </>
  );
}

Something like that, another option is to move the data fetching and the UI rendered with that data to a second component and use the handleClick to control if you should render it or not.

function RenderOnClick() {
  const [shouldRender, setShouldRender] = React.useState(false);
  function handleClick() {
    setShouldRender(true);
  }
  return (
    <>
      <button disable={shouldFetch} onClick={handleClick}>Fetch</button>
      {shouldRender && <FetchAndRender />}
    </>
  );
}

function FetchAndRender() {
  const { data } = useSWR("/api/users/1", fetcher);
  return (
    <>
      {data ? <h1>{data.fullName}</h1> : null
    </>
  );
}

Both ways will only start fetching after you click the button, I would personally go with the second way.

@loveholly
Copy link
Author

Thanks a lot

@millenjo
Copy link

I would also go with the first example, It doesn't force you to split code into different chunks when not needed. The first example also allows for a better separation of logic and view data which is always good!

@anabeatrizzz
Copy link

@sergiodxa what if I have to pass parameters to fetcher function on click too?

@elie222
Copy link

elie222 commented Dec 26, 2021

Seems strange that this is still the best way to do this

@shuding
Copy link
Member

shuding commented Dec 26, 2021

Please take a look at #1450 and give feedback — we are working on a new hook for it 🙏

@venuziano
Copy link

@anabeatrizzz did you find anything about how to pass parameters to fetcher on click? I need to do that and i'm wondering how. Tried to use useState but it didn't work properly.

@anabeatrizzz
Copy link

@venuziano you can have a look at the documentation that explains about arguments.

@maxymapp
Copy link

You should use useSWRMutation instead.

The remote mutations are only triggered manually, instead of automatically like useSWR.

Conditionally setting the URL looks hacky, IMHO:
const { data } = useSWR(shouldFetch ? null : "/api/users/1", fetcher);

@elie222
Copy link

elie222 commented Dec 20, 2022

I would recommend using fetch for mutations instead.
If you're doing GET requests then useSWR and the previous code isn't hacky at all. Works great:

const { data } = useSWR(shouldFetch ? null : "/api/users/1");

We us that pattern a lot because we often don't have all the data for the fetch on pageload.And you can't do if (!shouldFetch) return null due to the rules of hooks.

@Ding-Fan
Copy link

I'm using useSWRMutation , looks good to me.

export function useCalculate() {
  let theURL = null
  theURL = `/api/calculate?`

  let { data, trigger } = useSWRMutation(
    theURL,
    (url: string, { arg }: any) => {
      // console.log('fetch arg', arg)
      return fetch(`${BaseURL}${url}${new URLSearchParams(arg)}`).then((res) =>
        res.json()
      )
    }
  )

  return {
    trigger,
    data,
  }
}

@elie222
Copy link

elie222 commented Dec 30, 2022

Is there a benefit to this approach instead of just doing:

onClick = () => fetch(`${BaseURL}${url}${new URLSearchParams(arg)}`)

@xprommer
Copy link

xprommer commented Feb 1, 2023

sure you can use this approach but still you have to handle data, error, isLoading
and the most important thing you have to manually update the state with it.
Also SWR supports many more features such as caching, revalidating, prefetching and more ...

@huypham1411
Copy link

huypham1411 commented Oct 9, 2023

so in my case, I need to call the API the first time, and then I need to recall it when I click on a children's component button
this is a quick demonstration of the scenario
parent component load (call API) -> children make changes and press the button to call the API again to update the parent

Any suggestion on how to handle this? Appreciate any help

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

No branches or pull requests