Giter Site home page Giter Site logo

Comments (26)

phryneas avatar phryneas commented on June 14, 2024 3

The fallback option would be absolutely not fitting here, and regularly go against user expecations.

We have cache collection of data that's not used anymore.

Imagine your hook starts out with initialData from 3am.
Then you fetch and get data from 5pm.
Then your component unmounts for a minute, the new data gets removed from the cache.
The next moment your component mounts again you are back at data from 3am.
Your data would go backwards in time.

from redux-toolkit.

duskpoet avatar duskpoet commented on June 14, 2024 1

Like what? The initial state can behave like the request successfully made behind the scenes, so it should be the same as the current behavior.

from redux-toolkit.

duskpoet avatar duskpoet commented on June 14, 2024 1

Is there any example of how to achieve this with rehydration? The docs on the topic are very scarce, and the API is complicated.

from redux-toolkit.

phryneas avatar phryneas commented on June 14, 2024 1

That was my step 1 above, yes. "Dump your api slice..." ;)

from redux-toolkit.

amitdahan avatar amitdahan commented on June 14, 2024 1
  1. On the server, make all requests with RTK Query

In my case, the server is written in Go, is this the only option for using extractRehydrationInfo?

from redux-toolkit.

phryneas avatar phryneas commented on June 14, 2024 1

Unless you have a custom middleware that is async, the reducer will always execute synchronously on dispatch and the store will be populated with the required data to fulfill any request.

from redux-toolkit.

hardikhere avatar hardikhere commented on June 14, 2024

@duskpoet
you can give a default value when using this hook, useGetUsersQuery()
const {data = initialState} = useGetUsersQuery()

from redux-toolkit.

duskpoet avatar duskpoet commented on June 14, 2024

But that would unwillingly trigger the api request

from redux-toolkit.

hardikhere avatar hardikhere commented on June 14, 2024

yeah makes sense to have an initial state but might create some confusion in error cases and refetching cases

from redux-toolkit.

markerikson avatar markerikson commented on June 14, 2024

You should be able to do this via the hydration process:

https://redux-toolkit.js.org/rtk-query/usage/persistence-and-rehydration

from redux-toolkit.

hardikhere avatar hardikhere commented on June 14, 2024

Yes hydration is fine but useSWR has better way, they take fallback object, maybe we can take some inspiration from there
https://swr.vercel.app/docs/advanced/understanding.en-US#fallback

from redux-toolkit.

duskpoet avatar duskpoet commented on June 14, 2024

I can try to prepare a PR if this feature does seem reasonable.

from redux-toolkit.

phryneas avatar phryneas commented on June 14, 2024

Like I said, I'd rather avoid it - it can be quite confusing. I'd assume that for what you want right now, you could use rehydration.

from redux-toolkit.

DaniAcu avatar DaniAcu commented on June 14, 2024

@duskpoet Maybe you are looking for something like api.util.updateQueryData

https://redux-toolkit.js.org/rtk-query/api/created-api/api-slice-utils#updatequerydata

from redux-toolkit.

duskpoet avatar duskpoet commented on June 14, 2024

@DaniAcu yea, that's a possibility, though it complicates the usage - need to issue this call and wait for its effects before attaching the store to react, otherwise, there will be an unnecessary API call.

from redux-toolkit.

phryneas avatar phryneas commented on June 14, 2024

Is there any example of how to achieve this with rehydration? The docs on the topic are very scarce, and the API is complicated.

Sorry I didn't get around to answer back then.

  1. On the server, make all requests with RTK Query. Dump your api slice into a script tag or something that will end up in a window.foo global in the browser.
  2. In your api:
createApi({
  // ...
  extractRehydrationInfo(action) {
    if (action.type == "rehydrateMe") return action.payload
  },
})
  1. In the browser
store.dispatch({ type: "rehydrateMe", payload: window.foo })

from redux-toolkit.

DaniAcu avatar DaniAcu commented on June 14, 2024

@duskpoet I found that extractRehydrationInfo should return the state structure specifically for a createApi slice, maybe the case that @phryneas shared is not enough for your case. I found this work around checking the internals of the library, maybe it could helps you in this case.

import { nanoid } from "@reduxjs/toolkit";

createApi({
  // ...
  extractRehydrationInfo(action) {

    if (action.type === "rehydrateMe") {
      return {
        queries: {
          "getUser()": {
            status: 'fulfilled',
            endpointName: 'getUser',
            requestId: nanoid(),
            originalArgs: "",
            startedTimeStamp: Date.now(),
            data: action.payload,
            fulfilledTimeStamp: Date.now()
          },
        },
        mutations: {},
        provided: {},
        subscriptions: {}
      }
    }
  },
})

Then you could dispatch:

store.dispatch({ type: "rehydrateMe", payload: window.foo })

from redux-toolkit.

phryneas avatar phryneas commented on June 14, 2024

@amitdahan
You can also dump an api slice once, look at it's shape and replicate that in go, but you might need to re-do that at one point in the future if we change our spi slice shape.

from redux-toolkit.

duskpoet avatar duskpoet commented on June 14, 2024

This approach still requires to hold off react mounting store to avoid the api request, right?

from redux-toolkit.

phryneas avatar phryneas commented on June 14, 2024

How else would you provide "initial data"?
Yes, you have to know the initial data before you mount your React component that needs that initial data.

The example you gave in the initial post would require that, too.

from redux-toolkit.

duskpoet avatar duskpoet commented on June 14, 2024

in our case we have it injected into the page by server renderer, so we can access it like a global variable anytime in the javascript code

from redux-toolkit.

DaniAcu avatar DaniAcu commented on June 14, 2024

@phryneas Ou I didn't get well then, sorry. I hope the example helps in some way at least.

@duskpoet I think depends on what you mean by "hold off", the dispatch should run before render. But doesn't need to wait for anything.

In my exploration I did:

dispatch({ type: 'Hydrate', payload: window.foo })


const root = createRoot(document.getElementById('root'));

root.render(<App />);

And didn't throw the request because it was already in the store. I would recommend pay attention to parameters of the endpoint but you don't have params in you getUser endpoint.

from redux-toolkit.

duskpoet avatar duskpoet commented on June 14, 2024

Right, in our case, the store is created inside the react tree cause it depends on the routing, so it goes deeper than the react router. And I think the following wouldn't work too:

  const store = createStore(...);
  store.dispatch({ type: 'Hydrate', payload: window.foo });
  return (
    <Provider store={store}>
       {children}
    </Provider>
  );
}

because of the thunk middleware

from redux-toolkit.

phryneas avatar phryneas commented on June 14, 2024

because of the thunk middleware

What do you mean by that?

from redux-toolkit.

duskpoet avatar duskpoet commented on June 14, 2024

If the chain of reaction to this action will emit an async action, then the react effect may fire first, initiating the API request

from redux-toolkit.

duskpoet avatar duskpoet commented on June 14, 2024

Ok, thanks! Let's close the issue then

from redux-toolkit.

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.