I have a question about possibilities of data pre-loading with nuxt.js
I'm currently working on a project that is strongly coupled with back-end data and I stumbled on some difficulties.
I would like to save some data in localStorage to speed up the navigation within my website, the data consist of dictionaries containing (key: value) pairs that I use to resolve item properties names that come from api calls on query for specific item. (oh and they can possibly change in the future with more languages coming)
When the localStorage wasn't initiated (first visit/storage cleared/disabled) I would like to fetch that data to Vuex store so I can use store getters in Vue components.
Some problems emerge with my approach as localStorage is available from mounted() and not before that point in components life cycle. So I can't detect if there is any cached data before the whole page is already rendered.
I would like to hear any ideas, is there any workaround, maybe this way of cashing data is simply wrong. I'm just at the beginning of front-end journey.
Sidenote - I have wrote a custom plugin for async calls to api but Nuxt renders all components before I even commit the chages to Vuex store.
Related
I'm constructing a React App that is basically a photo sharing app.
Here's some use cases:
User can upload photos and videos
User can see the photos in a list view
User can reorder the photos in the list
User can select photos from list and performs actions based on their selection
Users can attribute properties to these photos, such as message, title, etc. Lets call an image + its properties a Post
Here's some major architectural components:
A CDN service to upload, host, and transform image and video creation
A backend application paired with a DB for persistent storage
I'm looking for a good way to organize all this data in state. One thought I had was to break up the state into separate, simple data structures.
Roughly this:
posts <Array> maps Post index to Post ID
media <Object> maps Post ID to Image Urls
selectedPosts <Object> maps Post ID to Boolean
loadingPosts <Object> maps Post ID to Boolean
So here we have four data structures.
posts: Determines what posts are in state and in what order
media: Attributes Post IDs to Image URLs
selectedPosts: Determines what posts are selected
loadingPosts: Determines if a given post is loading or not
I'm surfacing these via four React Contexts
Breaking up state into separate contexts makes it really easy for dependent components to subscribe to exactly the state they need. For example:
import React from 'react'
import useMedia from '/hooks/media'
export default ({ postId }) => {
const { media } = useMedia() // useMedia uses useContext under the hood
const imageForThisPost = media[postId]
return (
<Image src={imageForThisPost}/>
)
}
What I really like about this is that this component gets exactly the state it needs from global state and really only has one reason to re-render (pretend i'm using useMemo or something). I've worked with some tough React Redux web apps in the past where every component re-rendered on any state change because all the state was in one data structure (albeit memoized selectors could have fixed this).
Problems arise when it comes to use cases that impact multiple contexts. Take uploading an image as an example:
The sequence of events to upload a photo looks like this:
An empty post with ID, "ABC", is selected. Update selectedPosts context
User uploads a file and we wait for CDN to return image url
Update loading context of post ABC (loading == true)
(receives image url)
Update posts context at ABC
Update media context at ABC
Update loading context of post ABC (loading == false)
Deselect post ABC. Update selectedPosts context
Long, intricate, async sequences like this are tough to deal with, encapsulate, reuse, and test.
What's a better way to organize state for medium sized web applications like this with potentially long sequences of async actions and somewhat complex state?
Wishlist:
Easy to control re-renders
Easy to add extend/change app functionality (not a fan of huge deeply nested data structures)
Easy to test
Does not use Redux (but useReducer is fine) (I just don't like the huge overhead that comes with redux)
Anyone have any thoughts?
I know one way might be to emulate Redux using useReducer, actions, and selectors. And thankfully dispatch is a stable function identity in React. Idk, I just really don't like dealing with big, deeply nested objects. When product requirements change, those are such a pain to deal with because the entire application depends on a particular schema shape.
Old post, but am assuming that selectedPosts and loadingPosts are filtered posts objects.
Personally I would probably not have them as separate, but filter of posts which are marked loading / selected and upload those in code via some action?
I.e. state has list of posts, with loading / selected props and code does the filter on posts to upload - are you over complicating it? Presuming with some lookup one to many / many to many? on state for media to create the association? What did you end up doing? I would be using useReducer and dispatching updates to state, not sure context is needed unless its deeply nested.
tl;dr: Why not pass variables by reference between components to have them work on the same data instead of using e.g. BehaviorSubjects?
I'm writing a sort of diary application in Angular 8. I have two components (Navbar and Dashboard) and a service (EntryService).
Navbar lists the entries, Dashboard provides the textarea, EntryService glues them together and communicates with the database.
While debugging the application I stumbled upon a way to communicate between the service and a component that i haven't thought of before.
By accident I passed a variable (entry: Entry) from the Dashboard by reference to the EntryService. The service saved to the database getting a unique ID back and saving this ID into the entry variable. This change immediately reflected to the Dashboard because of the 'passing by reference'.
Until now I was using Subjects to update the components on changes, but passing references around seems to be much simpler, because I want to work on the same data on both components and the service.
I've studied Angular for a while now and not read about this approach, so I'm wondering if it is a bad idea or design and if yes why?
Thanks for your answers!
Passing by reference can be handy. But as a general approach to keep the application components in sync it has some draw backs. With Subjects you can easily investigate in which places of the application the value of the Subject will be changed by checking where the Subject.next() function is being called. When you pass your object by reference to a hundred components/services it will be much more difficult to find out, which of them modify the object and more importantly when, becaue often you want to trigger other changes afterwards. When you subscribe to Subjects, you get notifications about changes and can react to them. Subjects and Subscribers are an example for an Observer/Observable pattern, it allows you to decouple your application logic. And they are much more flexible, for example you can have a Subject which can return the last x number of changes or you can debounce the changes when you track user input, you can apply filters to them etc.
I'm working on a React application that is connected to a few ASP.NET Core WebAPI microservices. Each of these services have different entities that are used throughout the application.
Within the complete application, there are enums and 'configurational data' that can be configured.
Imagine configurational data as just simple tables, with two fields (Id and Value).
Different entities have FK relationships to the configurational data, and/or have enum fields. I'm trying to understand how I would, in a performant way, can load the configurational data and all the used enums upfront upon page load, so that these can be used in dropdowns. I'm pretty new to React (1 month), so still learning day by day.
I've initially taken the approach of writing a custom DropDown component that accepts a WebAPI GET url, to fetch the possible values for a certain table or enum, but it's very impractical and will prove to be not so performant once there are 1000 users using the application, and all doing calls to these api's multiple times, just for some dropdowns.
So, what is the advised approach to have some sort of splash screen in React AND call APIs to cache values, that then can be used in other components?
"I've initially taken the approach of writing a custom DropDown component that accepts a WebAPI GET url"
You should not do this :)
Before I suggest a solution I want to go through a couple of important key concepts.
Firstly
The render method will always run once before you async stuff happens (like your GET).
Lifecycle methods order which will trigger the First Render : constructor => componentWillMount => render => componentDidMount.
This means that you will have to have all your data ready for render initially. Or have conditions which prevents certain jsx for being called.
Secondly
If you have dynamic content, which will be the options in your dropdown, you'll have to get it from somewhere. If it's static you can define a list locally.
If you want to save the response you could use localStorage or if you are using redux; the middleware redux-persist to persist the store.
I personally don't see the purpose though, because if the dynamic options updates you would want that to update the application state. And even 1000 simple calls like that is not expensive for the server.
If you are using redux, you should keep the options there, because then you won't have to make an GET every time you're mounting the component with the dropdown.
Suggestion:
Many ways you can do this but here is a simple solution).
keep a local state in component and initialize it for first render
this.state = {dropDownOptions: []}
Then in componentDidMount make api call:
fetch(url).then((response)=>this.setState({dropDownOptions: response}));
And lastly in your render method:
<MyDropDown options={this.state.dropDownOptions} .../>
What is the difference (benefits/cons) of using Vuex vs a service for state management.
I am working on an application that displays a catalog of items. These items are fetched from an API. At the moment users have the ability to apply filters and sort the items.
I am using a service to handle updating the view based on what filter the user applies. The items are filtered on the back end so each time a filter is triggered an update method fetches the items from the API.
There's a few levels of component nesting for this application (and these are reused among diff pages with sim functionality) and I used an event bus as a quick way to handle the events and test the API endpoints, but now I need to use Vuex to handle the state.
I am starting to write the Vuex store and I am noticing there's quite a bit of functionality that I'm transferring over from the service.
I would like to know how the too differ?
I'm relatively new to VueJS, so please take this with a grain of salt.
I think it depends on the size of the app, as well as the complexity. If you're emitting a lot of events, using state makes sense because you have a single source of truth (a single file, literally) for your app state vs an event bus which will have to be imported into every component. From the Vuex site,
If you've never built a large-scale SPA and jump right into Vuex, it may feel verbose and daunting. That's perfectly normal - if your app is simple, you will most likely be fine without Vuex. A simple global event bus may be all you need. But if you are building a medium-to-large-scale SPA, chances are you have run into situations that make you think about how to better handle state outside of your Vue components, and Vuex will be the natural next step for you. There's a good quote from Dan Abramov, the author of Redux.
Hope this helps. Good luck :)
I was looking into how secure a redux application can be, I am storing certain values in redux store i.e. user token etc.. and tried to see if someone else could gain access to them via an xss attack for example, I checked sessionStorage, localStorage, cookies and it is not there, as well as it is not inside my app.js file (my bundle file), hence my question.
Was just about to answer How does React and Redux store data? Is it localstorage or cookies? when it got closed as a duplicate. So I wanted to paste my answer here.
Answer
First off, it's worth noting that UI libraries don't actually manage state (other than component-level state). ReactJS and VueJS expect you to pass data to them like you would pass parameters to a function. They aren't concerned with where this data came from or how you're storing it.
Redux, on the other hand, is not a UI library -- it's a state management library. Redux does store state. The VueJS corollary to Redux would be "Vuex".
With that out of the way, the next thing you need to know is that there's a difference between state management and state persistence. Libraries like Redux and Vuex usually keep track of your variables and provide tools for changing state (reducers, specifically) - but they don't manage the persistence of that state. Persistence refers to saving the state somewhere to reload it the next time someone comes to your app - and seems to be what you're curious about (since you mentioned cookies and Local Storage)
Persistence is usually coded by hand (send the state to an API endpoint which saves it to a database, then when you reload the page you ping a different API endpoint to retrieve the state) or you utilize a plugin / module for your state manager to handle persistence for you. For example, there's a popular Redux Local Storage plugin called (trivially enough) redux-localstorage
From this part of documentation (http://redux.js.org/docs/FAQ.html#performance-state-memory) I deduce it's stored in memory, so it is not persistent.
The state in Redux is stored in memory. This means that, if you refresh the page the state gets wiped out. The state in redux is just a variable that persists in memory because it is referenced by all redux functions.
A misconception is:
In redux, we know that the state is stored as an object.
This is not correct. State in redux can be any valid JavaScript value, not just an object. It just usually makes the most sense for it to be an object (or a special object like an array) because that allows for a more flexible data structure (but you could make the state just be a number for example, according to your need).
Redux use internal memory for all data. For example, when you subscribe to Store, Redux just push listener to private array and do not use Cookies or LocalStorage.