Coder Social home page Coder Social logo

Comments (20)

sergiodxa avatar sergiodxa commented on May 14, 2024 108

SWR is more intended to get data, not update it, usually you have another function to update and after it you will run mutate to update the cache and trigger a revalidation (SWR will fetch it again)

from swr.

shuding avatar shuding commented on May 14, 2024 93

UPDATE 2022.6:

SWR 2.0 beta now has a dedicated API for one-off requests such as POST. Docs and examples can be found here:

https://github.com/vercel/swr/releases/tag/2.0.0-beta.0

It also supports many good things such as cache population, error rollback and race condition prevention.


Original answer:

function App() {
  const { data } = useSWR('/api/data', fetch) // <--------------GET

  return <>
    {data}
    <button onClick={() => {
      fetch('/api/data', { method: 'POST', body: ... })  // <---POST
    }}>update data</button>
  </>
}

You can just use fetch for POST requests. I don't see the benefit of allowing POST in SWR.
And most importantly, most of the great features will be gone with POST (because it's not a "pure" action like GET, which is perfect for fetch-as-you-render):

  • stale-while-revalidate (SWR)
  • focus revalidate / polling
  • automatically request deduplication
  • caching
  • ...

But speaking of revalidation/mutation, it's still a thing for allowing POST together with SWR. Currently we need to do this:

mutate('/api/data', newData, false) // local mutate without revalidation
await sendPost('/api/data', newData) // POST request
trigger('/api/data') // revalidate

Maybe we can simplify it to something like:

mutate('/api/data', newData, sendPost)

which will do the exact same thing as above.

from swr.

nicolasschabram avatar nicolasschabram commented on May 14, 2024 23

Maybe it'd be worth checking out react-query's useMutation() hook for reference as well.

from swr.

eric-burel avatar eric-burel commented on May 14, 2024 16

Answers here are assuming that POST = data mutation
However POST is legitimately needed when doing list filtering that will explode the URL limitation of GET requests.

Multiple arguments help a lot here, the second argument can be "fetch" call options: https://swr.vercel.app/docs/arguments#multiple-arguments

from swr.

DeepakKapiswe avatar DeepakKapiswe commented on May 14, 2024 11

I Used like this and it worked for me, please let me know If Iā€™m missing something

let url = 'some url here';

export default function ComponentName  (props) {
  const fetcher = (...args) => fetch(url, {
    method: 'post',
    headers: {
      "Content-Type": "application/json"
    },
    body: JSON.stringify(props.payload)
  }).then(res => res.json())

  const { data, error} = useSWR(url, fetcher, { suspense: true });

from swr.

monman2l avatar monman2l commented on May 14, 2024 10

const fetcher = params => url => post(url, params)
const { data, error } = useSWR('/api/user', fetcher({key: val}))

This way?

from swr.

pedronauck avatar pedronauck commented on May 14, 2024 7

So, this should be work in the newest version (dependent data and multiple params):

const { data: user } = useSWR('/api/user')
const params = useMemo(() => {
  return { username: user && user.username }
}, [user])

const profile = useSWR(() => ['/api/profile', params])

Because I'm trying this and I'm getting an infinite loop always šŸ˜•

from swr.

shuding avatar shuding commented on May 14, 2024 4

@iammarkps thanks for elaborating! šŸ‘

Now I can understand your use case, it makes perfect sense.

Can SWR pass 2 arguments to functions?

And yes! This feature will solve the problem: #98

We just shipped it to [email protected] and you can use it but the documentation is not yet updated. Ideally your code will be:

useSWR([type, param], fetchFromFirebase)

But keep in mind it compares arguments shallowly, so keep in mind to memorize the object:

const param = useMemo(() => ({ submission_id: id }), [id])
useSWR(['getDetailedSubmissionData', param], fetchFromFirebase)

from swr.

iammarkps avatar iammarkps commented on May 14, 2024 1

@quietshu Thank you! I've just improved it with your suggestion in this commit

from swr.

sergiodxa avatar sergiodxa commented on May 14, 2024

This example https://github.com/zeit/swr/tree/master/examples/optimistic-ui does something similar, update and then revalidate

from swr.

iammarkps avatar iammarkps commented on May 14, 2024

I have a use case with firebase onCall function(which it's method is POST). Because it supports authentication by default, I have to use this workaround.

import firebase from '../lib/firebase'

export const fetchSubmissionData = async (id: string) => {
  const getSubmission = firebase
    .app()
    .functions('asia-east2')
    .httpsCallable('getDetailedSubmissionData')

  return await getSubmission({ submission_id: id })
}

Then I can use

 const { data } = useSWR(`${id}`, fetchSubmissionData)

My function is onCall because it needs to verify user before sending back data.

Any idea on improving this? @quietshu

from swr.

shuding avatar shuding commented on May 14, 2024

@iammarkps can you show me a POST example you have without using SWR?

from swr.

iammarkps avatar iammarkps commented on May 14, 2024

I always use it that way. But I'm just curious that, can I have only 1 global function to use firebase callable function?

Now I have to implement 3 different functions with same logic.

https://github.com/programming-in-th/programming.in.th/blob/master/src/utils/fetcher.ts

Because firebase callable function receives 2 args, not 1 like normal GET request(Just url of API).
Can SWR pass 2 arguments to functions?

PS.Pardon my bad english

from swr.

iammarkps avatar iammarkps commented on May 14, 2024

I've used to do this when I was using redux (It's POST method).

https://github.com/programming-in-th/programming.in.th/blob/83ff9a23648e9ece55f8abeb555292da28908dac/src/redux/actions/submission.ts#L24

and this for normal data fetching (Still POST method)

https://github.com/programming-in-th/programming.in.th/blob/83ff9a23648e9ece55f8abeb555292da28908dac/src/redux/actions/task.ts#L34

But now I've converted it to normal http GET not firebase callable anymore.

https://github.com/programming-in-th/cloud_functions/blob/master/functions/src/tasks.ts#L4

So it works perfectly with SWR.

But I can't convert this to http GET, because I have to check user right to access the code in line 187. So I need to depend on firebase request context. @quietshu

from swr.

iammarkps avatar iammarkps commented on May 14, 2024

I want to do this


export const fetchFromFirebase = async (type: string, param?: Object) => {
    const get = firebase
    .app()
    .functions('asia-east2')
    .httpsCallable(type)

  return await get(param)
}

from swr.

shuding avatar shuding commented on May 14, 2024

@iammarkps looks great!

from swr.

shuding avatar shuding commented on May 14, 2024

@pedronauck oh that's because you're using a function which returns an array here:

const profile = useSWR(() => ['/api/profile', params])

This case is not yet covered (thanks for reporting!), for now you can just use an array:

const profile = useSWR(['/api/profile', params])

from swr.

theweiweiway avatar theweiweiway commented on May 14, 2024

Hi! Great library, I had a quick question:

const profile = useSWR(() => ['/api/profile', params])

Right now, it's fetching whenever any attribute of params changes. Is there a way for me to programatically make it fetch with updated params only when a specific attribute of params changes?

Thanks

from swr.

sergiodxa avatar sergiodxa commented on May 14, 2024

You need to pass every attribute inside params as different elements of the array.

from swr.

yufengwang avatar yufengwang commented on May 14, 2024

mark

from swr.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    šŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. šŸ“ŠšŸ“ˆšŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ā¤ļø Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.