Server rendering with react-router v4 and prefetching data - javascript

I worked a lot with server side rendering with RR 3 so I wanted to see how it works in the context of v4. I followed the tutorial from the website, but because the rendering is happening now together with the route match, there's no way to implement prefetching data as before.
Here's how I used to do server rendering with v3:
https://github.com/alexnm/react-seed/blob/master/server/index.js
Based on the match function, I would call all the prefetch functions from all the component tree and then wait with a Promise.all for them to finish, then trigger the renderToString function and return the html.
In RR4, we have only the <ServerRouter> component, so the current solution I came with is duplicating the render code:
https://github.com/FortechRomania/react-redux-complete-example/blob/master/src/server/index.js
I'm also using the render function on the <Match> tag to trigger the prefetch actions. It's ugly and introduces all sorts of dependencies in the parent component of the page I want to render with prefetched data.
What am I missing here? Has anyone found a better solution for this scenario? I haven't found anything useful yet.

The new RR4 documentation has a working example: https://reacttraining.com/react-router/web/guides/server-rendering/data-loading

Related

What is the best way to fetch data only once in react?

so let's say I have a react dashboard application, which has several different routes. Now, one of those routes is Analytics route, and I was wondering, if is, what is the best way to fetch the data rendered in Analytics route only the first time you visit it and then pull it from somewhere.
I've been thinking about using Redux for it, but I've never used it, so I have no idea, OR if I should store it in localStorage. But that has a problem though, because on different route, I would like to fetch images the same way.
The reason I'm asking this is because I use Firebase Firestore as my DB and it could get quite costly, because I would have to do 4 read operations i.e. on the Analytics route each time it is rendered. Or, is it the normal approach?
Is it a good idea to use React Context and useContext hook in this case?
Thanks in advance.
use redux for state management, where you can store the application state and the components who need data. You can call Api in order to fetch data only first time in the root component of the app.
use react-query you can do exactly this in a much simpler way as compared to context or react-redux.
you can use a useEffect hook and do an api call each time you visit that page and you don't have to store it anywhere and it will only get you the date you need i recently made an app and this way actually helped me alot

How does React remove asynchronous behavior?

I have been reading this, and I came across a line in the Redux documentation
Libraries like React attempt to solve this problem in the view layer
by removing both asynchrony and direct DOM manipulation.
I understood the part where React does not allow DOM manipulations as it abstracts the actual rendering using the render() method. I am confused with the second part.
How does React remove the asynchrony? Can someone please explain with examples or valid use cases.
It removes asynchronous behavior from the view layer by design. You must not do async stuff in render or what is rendered will be broken.
Libraries like React attempt to solve this problem in the view layer
by removing both asynchrony and direct DOM manipulation [from the render method].
You are missing the last sentence which gives further explanations:
However, managing the state of your data is left up to you.
This is where Redux enters.
To wrap up, there must be no async calls in render method but there can be some async stuff happening in the state management part handled by Redux. You can't do async stuff in the render method by design. If you you do so it won't work.
I think that good example would be an rendering library like dust.js
It renders template asynchronous, creates document fragment, and let user handle appending in callback.
And well... I think that any DOM mutations performed in callbacks counts into this case.

Ember.js - How share route model-data between more routes? - Why not load data in component?

TL;DR
Embers components are just smart HTML-Templates. Why they don't fetch their data for themselves like Angular? And how I can share route models over more URLs/pages. It seems that I have to know wich components are placed on which URL and I have to make them the data available over the route models. Why is this part not in the component?
I learn at the moment Ember.js. I try at least.
At the moment I have a strong problem to understand why Ember.js acts like it does. Please correct me if I am wrong at some statements. I am an Ember.js beginner. So maybe its not right what I point out here.
Lets say we have a Request on / then Ember tries to find a route model in app/routes/index.js this file contains the code which data I want to fetch from the backend. Next Ember will render app/templates/index.hbs in this file I have a component called car-list.
As far no problems but let us have a closer look. For me it feels very weird that I have to fetch at first the data by myself, why the component doesn't do this on its own? Next problem is then how can I share the model fetch logic between more routes? Maybe I want to place my component on many URLs/pages/routes then I have to copy the route model logic?
In my opinion, the component should fetch the data by itself, that you can easily insert the component on other pages without copy the whole route model fetch logic.
So I have to know wich components are placed on which URL and I have to make them the data available over the route models. Why is this part not in the component?
So maybe I am just not good enough with Ember and I just overlook something?
Components are very flexible. Components have made to be reusable. For example you can create a table component and use for cars, ships, etc.
So for reusability it's better you separate model providing from component.
But if you want to make a component which is for current project and need to fetch its data itself, you can fetch data in the component.
In some scenarios you might want to fetch data in routes. For example in your page you have multiple components and every component needs a projection of data model which fetched in route.
So it depends on your requirements, maybe you need to fetch data in component or in route or even both (mixed)
Components certainly can load their own data, and in many cases that is appropriate. But allowing the route to load the data has several important benefits that you get "for free" if you stick to that pattern:
your application's URL will always reflect the state of the data. You don't have to remember to synchronize it (in both directions -- changes to URL should change the data, and changing the data should change the URL).
you can write your templates knowing that they won't render until the data is present, allowing Ember to handle the asynchrony for you. This results in cleaner, simpler templates.
you get Ember's built-in error handling for when the data fails to load.
A username component that appears on many pages typically belongs fairly high in the route hierarchy anyway, like in the application template, where it's easy to load & render it once from a single place and have it remain visible on every child route.
But if you do need to use a component in many places and its data should be self-contained, it's fine to let it do its own loading. In that case you can either rely on Ember Data's store to give you cached responses (so you only trigger a network request the first time) or write a Service that handles some persistent state for your component.

How to do url/view routing with Mobservable, React and possibly React-Router?

I'm looking into mobservable but I'm having some trouble coming up with a good model to do url routing.
Because of how mobservable works with React using a standard react-router does nothing when you change the url. Only if we crudely pass the url path down into the Handler stack to make them reactive do I see some changes.
I feel this needs a different approach. Of course I could hack some custom thing but I kinda like react-routers way of nesting the urls and the solid Location/Link features.
I'm working a (non public) project that uses both mobservable and react-router. That setup is basically as follows:
Create all your routes, but give them all the same handler, your root component.
Introduce reactive state that stores your ui state (like, currently open document for example)
in the router.run callback, use the data that is passed in (the second argument) to update your ui state and to kick off the necessary data retrieval and such. In the end of the callback, just render your handler. Depending on your further setup of the root component you want to pass it the ui state or nothing at all.
For us that setup worked fine so far, so please let me know if you run into any trouble.
EDIT
Another setup using Director can be found in the Mobservable TodoMVC example
Linking this because I found it helpful. I am basically following the approach out here: https://github.com/contacts-mvc/mobx-react-typescript/blob/master/src/components/ContactDetails/index.tsx.
Initialize the store/model in the app's index page or wherever the routes are defined. Then pass the initialized store to the component. Inside the component componentWillMount grab the ID off the route and pass it to a function to load your data.
If you already had data loaded then make a method that changes the selected item. Make sure that select item property is observed and it should automatically update the UI. I think that is what #mweststrate means by UI state.

Initializers in React.js?

I am using react 0.13.1 in a rails 4.2.1 application with react-rails and browserify-rails. I am not doing a single page application, but instead adding react components on rendered pages and using the rails routing system.
When I load a page, I want to initialize a few things, but I'm not sure where this code should go. Does react have a initializer function that it always calls before rendering components or does it always render the first component first such that I can just add initializer code to the first component?
How would I go about putting react initializer code in my multi page rails application? (should work for client or server rendered react code)
Note: Assume only react and plain javascript is being used.
Edit: not asking about initializing on each component, but rather initializing code after page load, but before react starts going through and rendering any components.
The entry point to initialize React is the call to React.render(), so you should perform any initialization before that call. If the initialization is async, just call React.render() in the callback.
And there's also the componentWillMount method on every component which can be used for component specific initialization.
Yeah it's all there in React's documentation. Each component has a getInitialState which is called when the object is first requested, you then have oncompentdidmount and another for when the component is dismounted. It's all JavaScript code so initialization code can be done inside each component or just declared globally before or after the React code is executed.
I have a similar setup with Django, where I use Django for it's strengths. Routing, Sessions, Authentication, Rest API ect... and have Django render a bar bones template which loads the React UI. This process seems to work really well, it's greatly sped up my site from where it was before, and the UI is awesome.
So in one particular case with my django app I need certain data to be initialized before the React components try to render themselves. therefore I wrap the initialization code into a function which is called on page load, then as a callback after that function has completed I call another function that actually add's my react components to the page. From there each component has it's own initialization which you've said you're not interested in at the moment, but that is how I handled the situation.

Categories

Resources