I was looking to build a feed into a react app that as you were scrolling through it it will constantly fetch more data to display to you (it basically has no end). I was looking for a way to avoid re-rendering the whole feed every time new data was fetched to be displayed to the user since it will start to get slow to re-render the whole component after a while.
I know I can do it with server-side rendering or through ReactDom.createPortal to render the element outside the react tree. The first option is out since that would be the only thing I would need a backend for and is not worth it.
The second option looks like the way to go but I am not sure if I can still access the state object and other react features from within the component rendered outside the react tree (I don't know if I would really need them or not but having them can't be bad)
Outside those two options, is there any other that I am not aware of?
Related
I'm new to react and I want to build a Spotify clone which lets me control my playback. Therefore I'm fetching the API every second to get the current data.
So far everything works just fine but I'm asking myself what would be the best way to display the current data in the browser.
Right now I'm using a useState for the current data which rerenders my code including the DOM and displays the data every time I set the useState. As this happens every second I have my concern if this is performant.
Are there any best practices or concepts I can use? I was thinking about setting the current data via innerHTML as with that I could avoid rerendering my component every second.
Thanks for every answer!
I'm learning react and having some trouble getting my head around some code design. I have a Session component that has several Activity components in my project. In the Session component I also have a Timeline component and I need to show the total duration of all of the events. So I need to have the start time for each of the Activities in the Session component and the end time of the last. I know of "lifting state up", but I find it a little strange in my OO way of thinking from C++ to store the data in the parent and not where it "belongs". What if I later need some other data from the activity.. Then I would lift parts of the Activity data up and store some of it in the Activity.. seems quiet messy?
I thought of also having a ActivityData object and store a list of them in the Session and pass that in to each of the activity to display it there. Another way I thought about would be to have a SessionModel object and a ActivityModel object and have this seperate from the component all together and pass these models in for rendering in the component.
I am also just getting into typescript and moving my code into that. I was thinking that I could define a custom ActivityData type in the same file as the Activity component and still store the list in the Session, but then at least its more explicit that the data belongs to the activity.
What is the right (or React) way of doing this?
You are right in your thinking and yes it isn't necessarily an OO way of doing things but more of a functional programming approach
Each component can have state, and it should store that state in it's own component. If that state is then needed by another component you can pass it down as a prop. However, if it isn't a child component that needs it then like you said you should lift state up.
The next problem happens when your app starts to grow. So then you need to make some choices. You should split your components up so they don't get too big. You can have some more logical components and then have some presentational components that don't handle logic but essentially just take props and render the views from you.
However, your app is still growing so at this point you might want to invest some time in introducing a state management tool to your app. React has the context
api built into so you can use that. or you could use a library likeredux. Redux is particularly good at abstracting state to a "global" store and you each component can "connect" to the store to access the state. Really good for apps where you have lots of shared state and lots of components need to know about similar pieces of state
In terms of Typescript then it's certainly a wise idea to include that as the language is heading that way. You can keep types in the same file or keep them in the same directory but have a .types.ts file that you import into your code and declare your types/interfaces in there
I'm building an app with React Native and on my transitions, where I'm loading more data, it's very slow and I'm wondering if there's a better way to structure my app to avoid these shutdowns, which get longer as the JSON file gets larger.
Let's say I have
var data = require('./data/data.json')
in my index view, I think pass this data to a view, which then splits it up to other views like items={data[section_name]} and it goes down recursively like that further down the hierarchy. Creating smaller dicts on each level. And even with small objects it is still quite slow.
The JSON files I'm working with are from 3-8 MBs.
I understand what you want do to with your big data in your project, because I did the same way before for my react-native app.
Actually, this way is fine, it's kind of loading the data once only, then we can retrieve hierarchy easily like items={data[section_name]}
However, the problem now is it may take a while for processing the big data!
Therefore, the idea is we should move the part of loading/initializing the data asynchronously, move it somewhere out of our view, so that the view's transition as well as its other things will not be affected! Then, when the data are being loaded/processed, we may show something like fade-in, fade-out effects, on the view, so it will take a short-time (300-1000ms). However, in my opinion, there may be a better way for this: when the application is opened for the first time, when the splash screen is being shown (for a few seconds, this behavior is common, we can load the big data in the background here!)
FYI, my application loads big data using ajax, it will even take longer than loading local files, but using my above-mentioned way, nobody complains about the data-loading speed ^^ (actually, users don't know and don't see where and when data are loaded, when the app goes to its home/top page, everything has been fully loaded)
Now it comes to the important part of my answer: I suggest you using Flux/Redux for this, maybe Flux is easier for you now, because Redux is kind of an improvement based on Flux (in either Flux or Redux, we will have a Store, and this Store will work asynchronously, you can store your big JSON data here):
https://www.atlassian.com/blog/software-teams/flux-architecture-step-by-step
Flux can be applied on reactjs and react-native of course, you may find there are several new definitions if you don't know about Flux or Redux yet, however, it's really worth reading and trying! After you understand it, it'll be very easy and then you can apply that architecture on whatever react project you like ^^
I'm looking for ways to structure state in my React components so that I can accomplish two goals together: (1) managing browser history in a complex app, and (2) letting individual components be easily reusable in environments outside the main app.
The app has a Panel component which lets users navigate and read content on our site. In the main app, multiple panels can be opened and arranged together. Outside of the main app, there are other pages where I'd just like to be able to easily drop in a single Panel component.
As this code has developed so far, each Panel has a rich state representing what content it has loaded and other display settings. This makes it easy to drop in to another page - I can just render a Panel component and the user can interact with it and it takes care of itself.
For browser history however, this is getting hairy. There is an App component which manages multiple Panels and the states pushed to and popped from history. In order for it to have a complete picture of the state of the whole app, each panel pushes up a copy of its state when changes occur. When state is popped from the history that App component can pass down an initialState from each of the Panels it renders. As you can imagine, this is getting messy and error prone with the cycles of updates that end up looping back to each other.
It feels like the approach I need to take is to Centralize State (a la the recommendation here) and try to make each individual Panel stateless. Since it will be a significant effort to rewrite all the calls to setState already in the code, I'm trying to evaluate if this is the only way to go. It also feels like this approach will make it harder to reuse the components outside the app. I'll lose the feeling that a Panel is a self-contained component which I can just render on a page, since it will need some kind of outside manager as well to handle its state and all the events that change it from within.
What would you recommend?
I made a application on react and implementing react-router you can pass throw the URL data to every panel know in what state are and what content is loaded, by example you can have an url like:
http://yoururl.com/index/user/userID1/item/itemID2/filterDate?="19/09/2014"
To reuse your panels you can made a url that made an herarchical route view: You can pass throw components everything you want to know on the render wich view you have to load.
My routerDomExample
I recommend to investigate react-router.
I have some data in IndexedDB, which can only be accessed asynchronously. I want to build a React.js UI using that data. The general idea is that I'll have multiple React components that load data from IndexedDB and display some UI based on that data, and the user will be able to switch between which component is currently displayed.
My concern is that I don't know how to elegantly accomplish this without some superfluous UI flickering. I can do my asynchronous data loading in componentDidMount and put the data in this.state, but then render will be called before it's finished, forcing me to either display nothing or display some placeholder data for a tiny fraction of a second while the data from IndexedDB is retrieved.
I'd rather have it not render until after my data from IndexedDB is loaded. I know it won't take long to load, and I'd rather the previous component continue to display while the new data loads, so there is just one flicker (old -> new) rather than two (old -> blank/placeholder -> new). This is more like how a normal web page works. When you click a link from one website to another, your browser doesn't instantly show a blank/placeholder screen while it waits for the server from the linked website to respond.
I'm thinking I could do my data loading outside of the React component before calling React.render and then passing it in via this.props. But that seems messy, because nesting components would become tricky and some of my components will be updating over time and pulling new data from IndexedDB, through the exact same code that initializes them. So it seems like an ideal use case for storing data in this.state because then I could update it within the component itself when I get a signal that new data is available. Initialization and updating would be as easy as calling a this.loadData() function that sets some values in this.state... but then I have the aforementioned extra flicker.
Does anyone have any better ideas? What's the canonical solution to this problem? Is it really to just have millisecond blank/placeholder flickers all over the place?
From the comments it sounds like the behavior you have in the previous implementation (waiting to navigate until you have fetched the necessary data) is the desired goal. If that's the case, the best way to do this without having the flickering would be to use some external object to manage the state and pass the data as props when it has been fetched.
React Router has a pretty good solution where it has the willTransitionTo hook to fetch data for a given component before navigating. This has the added benefit of allowing you to easily catch errors if something goes wrong.
Updated with new link:
https://github.com/reactjs/react-router