I am confused by the docs. I am trying to use Redux-storage middleware and this is how they show the store is created with the middleware:
const middleware = storage.createMiddleware(engine);
const createStoreWithMiddleware = applyMiddleware(middleware)(createStore);
const store = createStoreWithMiddleware(reducer);
But the Redux docs show this:
let store = createStore(
todos,
[ 'Use Redux' ], // How do I put here the data from the redux-storage?
applyMiddleware(middleware) // here goes the redux-storage
)
createStore requires an initial store value to be passed, but I can't load the stored values without having a store. This is a kind of catch 22. What did I miss here?
You actually miss nothing and that is intended behavior of redux-storage: there is a gap between creating redux store and the moment it got filled with the stored data. That is because storage engine provided to redux-storage createLoader can have an async nature in general case.
The common pattern to deal with that is following:
Your app starts up with uninitialized store state
It shows some kind of a preloader to your user
App creates loader and loads stored state: const load = storage.createLoader(engine); load(store);
Wait store to be rehydrated and hide preloader.
There is another store peristing lib out there: redux-persist. But initialization process works the same way, except you don't have to call load explicitly.
Related
Using Next.js next/router will cause a reload or it will retain Redux state?
import { useRouter } from 'next/router'
const DashboardSidebar = ({ mobile = false }: Props) => {
const router = useRouter()
router.push(
`/${lang}/dashboard/organizations/${organizationId}/events/${id}`
)
Or I should use redux-persist to retain state? When I follow this setup:
https://redux-toolkit.js.org/usage/usage-guide#use-with-redux-persist
I got this error:
redux-persist failed to create sync storage. falling back to noop storage.
Do I get it because I use Next.js and SSR?
Shall I move forward and use next-redux-wrapper?
https://github.com/kirill-konshin/next-redux-wrapper
Here are some instructions: https://redux-toolkit.js.org/rtk-query/usage/server-side-rendering#server-side-rendering-with-nextjs
As the user changes routes, the store needs to be rehydrated each time before the html is generated and sent to the client.
I am not a fan of this architecture. It seems strange that the store needs to be filled back up with its state (rehydrated) every time the user needs a new render. Where are you going to persist the store in the meantime? What is its lifecyle?
In a SPA, the lifecycle of the store is when the page refreshes (which would require a programmatic invocation, or the user navigating away and coming back, or pressing Ctrl+R). Conceptually, this is much simpler.
So, I am trying to access the cache that I set with: queryClient.prefetchQuery, in a SSR page.
I am using this on the SSR side that I hydrate:
ala:
await queryClient.prefetchQuery(['userSesion'], () => fetchUserSession());
// This is wrapping my _app.js file
<QueryClientProvider client={queryClient}>
<Hydrate state={props.dehydratedState}>
Then on the client side, I am trying to get at this "cache".
const queryCache = new QueryCache();
queryCache.find("userSession"); // <--- This is undefined/empty
Also tried: no luck
queryClient.getQueryData('userSession'))
queryClient.getQueryState('userSession'))
Mind you, I "SEE" the data/cache in the tools, so why can't I get at it?
because you create a new Cache, and that cache has no connection to the queryClient. If you want to get the cache, you can do this via:
const queryClient = useQueryClient()
const queryCache = queryClient.getQueryCache()
that being said, there should be rarely the need to interact with the QueryCache directly. The QueryClient exposes functions to interact with the cache, and if you have a component that needs data from the cache, it's always preferred to just call useQuery in that component. It will give you data from the cache instantly if there is any, and perform a background refetch if the data is considered stale.
I am currently building a like button on my card component in vue. I am fetching data from firebase using middleware on a page to dispatch the vuex action that will go and get my user info which has their liked_posts stored in an array.
The issue comes up that when I load a page requiring some of the data
i.e. liked_posts and my state is empty it throws a error of
"undefined".
How can I make sure that even if the user hasn't signed in or hasn't ever visited that my user data wont cause an error
I have tried to change my action in the Vuex store to be asynchronous and use await so that I made sure the data was there, but it didn't help.
What is happening is the below code in computed properties is trying to access an object that doesn't exist in the array yet.
likedOrNot() {
const likeInfo = this.$store.state.userInfoSub[0].liked_posts
return likeInfo.includes(this.$store.state.loadedCards[0].id)
}
This data isn't there yet because the user isn't signed in, exist ect. once they do and middleware is dispatching an action to fetch the user data the userInfoSub will be filled with info.
my base state looks like this when the user hasn't signed in or middleware hasnt fired to look for the user that gets put in cookies.
So I need away to ensure my lack of userInfoSub doesn't break my computer property
loadedCards:Array[1]
0:Object
token:null
user:null
userInfoSub:Array[0]
username:null
Here's an opinionated answer: use get from lodash.
npm i lodash
Then you can write something like this:
import get from 'lodash/get';
export default {
computed: {
isLiked() {
const cardId = get(this.$store, 'state.loadedCards[0].id');
const postIds = get(this.$store, 'state.userInfoSub[0].liked_posts', []);
return postIds.includes(cardId);
},
},
};
i have a problem protecting my routes using the store, when ever i tried to select some variable from the store its undefined and my page doesn't load because of that.
The store is working fine, here some pictures.
Initial State
State loaded
Console output
i recreate the problem here
https://stackblitz.com/edit/ngrx-guard-not-working
its the guard called before the store is init?
what can i do ?
You have to select the projects from the campaigns, your selector should look like this:
export const getCampaigns = createFeatureSelector<any>('campaigns');
export const getProjectState = createSelector(getCampaigns, state => state.projects);
I have recently begun coding in Redux.
Before Redux with AngularJS it was easy to map models with state using $localstorage. I just can figure out the best way to do that with Redux.
Should I be dispatching and action and ask reducers to read local storage for in my code ?
Or should I allow local storage to be managed with a global object ?
There are few ways.
Just note that for syncing to localStorage you need to call JSON.stringify which is quite expensive, so please don't do that often and also with large data structures as it might hurt app's performance.
1) Sync whole Redux store to Local Storage. You can use existing solution for that eg. https://github.com/elgerlambert/redux-localstorage
I would not recommend to sync whole store as you might sync also state which should not be persisted after refresh and also you might make application slower; For better performance you can use paths argument in above library or use one of another options.
To see how you can build such functionality manually, there is great explanation video from Dan https://egghead.io/lessons/javascript-redux-persisting-the-state-to-the-local-storage
2) Manually build simple cache middleware like below, which might catch specific actions you would like to sync with local storage
const cacheMiddleware = store => next => action => {
if(action.type !== 'GET_SOMETHING') {
return next(action);
}
const data = getFromLocalstorage();
if(!data) {
// Fetch and put to localstorate for later use
const data = fetchFromServer();
return next({ type: 'SERVER_RESULT', data });
}
return next({ type: 'CACHED_RESULT', data });
};
3) If you are using Redux Thunk you can perform caching there as you are allowed to have side effects in actions.
You can find more info about Redux middleware here https://redux.js.org/advanced/middleware