Loading dynamic layout in react from a remote API response - reactjs

How do I setup my react components in order to get the layout loaded from a remote rest based API? (I want the layout to be stored in a db so that it may be changed by the user whenever needed)
The API is a dot net core based API. It might be slightly difficult doing server side rendering. (Although that may be considered as well if there are no other options)
I essentially want to know if there is a way to send the jsx from the API. Is there then a way to return this jsx that I have received as the response from my component.

Related

React + SSR: Correct way to handle a component that needs to fetch data first

I currently have a React app that I'd like to use SSR with. All but one component is pretty much static content, making SSR super easy. Everything but the component is rendered just fine and well right now.
My question is how do I go about rendering this component that needs to first get data? Because it's a complex SVG that gets rendered my line of thinking is that having it "update" once data comes in is a bad move, and it would be better for it to just not exist in the absence of data (with an error message).
So here's my plan: I can add a prop to the component to pass in data from a parent rather than keep it as internal state only. So if data is passed, no fetch request in the component is necessary. From there what I can do is take the static bundle output of the app and, when the page is requested, the server will request the proper data just as the component would. Once the data is received, the server can grab the component from the bundle with regex, add the data as a prop, render the component, and stick it back in with the rest of the already rendered static content.
Is this the correct way to do this? It feels a bit complicated, but that might just be how it's done. I'm not sure.
Your intuitions are correct. In current React (17.0), it's quite cumbersome to do SSR with data-fetching inside components.
What needs to be achieved on a conceptual level is that all data dependencies need to be known upfront, ie. before calling ReactDOM's render. This way, one can access the data in a synchronous manner which allows to do one-pass render on a server.
I don't quite follow your idea to "grap the component from the bundle with regex". One way of solving the data dependency problem is to inject the data into React tree from the root component (ie. ReactDOM.renderToString(<App componentStaticData={data} />)) and make the data-dependent component aware of the fact that it can just grab the data from there instead of doing (asynchronous) call. It's important to note that useEffects are not executed on the server.
Another idea to grab all the data dependencies is to do two-pass render. First one is used as a way to collect all resources used, then we await their completion and inject them as static data into send pass.
Third way is to use one of the React frameworks that provide SSR out of the box. You can have a look at (among many others) Next.js or Gatsby. Depending on your setup, this might be easiest or the hardest way to achieve SSR.

Conditional Rendering on Server Side

Background
I am using next.js for server side rendering and react.js for client side.
Goal
Want to do conditional rendering on the basis of window size in server side. Like for 200px width render A component and for 400px width render B component.
Problem
In server side, we have no access to the window object and we have no idea about the device our client is using. So AFAIK we cant do conditional rendering on server side.
Thoughts
I have thought of some solutions, but don't know is it possible or not -
1. Send the device info or window object as json with the http request.
2. Don't render the conditional components in server side and re-render (hydrate) them on client side.
But I don't know what is the best practice and what is more efficient than other. New suggestions are also welcome.
Consider using next approach:
On server side you can predict device type by parsing user-agent
with help of mobile-detect package and pass expected values to
an isomorphic HOC created on top of react-sizes which allows to
setup "predicted" screen sizes to work on server side.
Wrap your conditional logic with appropriate to your business logic
structures with adaptive HOC you've created
...
Profit
Be aware of at least next cases you should take care of:
Narrow screens of desktop user-agents will be rendered as for
desktop, but might start re-rendering on client side, as MatchMedia
gonna do its work on client
Any caching layer should include parsed device type into cache key
so you will not cache potentially broken layout.
I had a few places with these conditions.
At the end I decided to only render conditional component on the client side as least problematic solution with smallest overhead.
Other solutions:
If its a component with an important SEO content and you need to render it (make it look a bit better if its rendered on a wrong size till react rerenders component depending on the screen size). Bare in mind this approach can introduce some bugs during rehydratation as react sometimes duplicates div's. You can set a new key for a compont to fix it.
You can also use css for hidding content.
You can know if the device is a mobile or not by using this piece of code in your server.js
app.get('*', (req, res) => {
var ua = req.header('user-agent');
if (/mobile/i.test(ua)) {
//mobile code
} else {
// desktop code
}
});
and you can pass this boolean in react and use it

What happens with the state in a React isomorphic App

I am building an isomorphic app with React that must support users without JS.
I am new in this technology and I have a basic doubt:
The server can store the components states to emulate what React does in the client-side?
I imagine this flow when the user dont have JS:
The user click a button and send a request to the server.
The server recovers the state of the app and makes changes in it.
The components listen this changes and are rendered again.
Is it correct?
Assuming that you're using react-router :
The server aims to initialize your state, to provide it the default minimum values necessary to make your application work while getting an url.
For example, if you have an application in which you want to display a user list, let say on /users URL, when you'll send your first request, the server will store the users in the react state.
After that first load, you'll be working on the client side using react-router, and making XHR request.
However, if you refresh your page, the process will start again : first load initializing the state and then client side navigation.
EDIT : Explanations =>
When you want to use react on the server, this means that you use a Nodejs server. The fact is that react-dom provides a method called renderToString that transform a react jsx component into standard HTML.
This aims to load the first call faster
Why ?
When you load a "big" JS application on the client, you have some delay time, the time your browser needs to download your JS bundle.
Server side rendering aims to avoid that behaviour, or at least, to gives the feeling that the app starts faster.
In no case you can only use react, even if you use your server side renders. Why ? . Because your events on buttons, or asynchronous load on client, or keypress are in JS language.

How to add universal support existing react project

I've created a react redux project, now how do I add some SEO functionalities to project? I do not want to waste much time while refactoring codes.
You need to setup the redux store on the server and pass its initial state down to the client, so that the server-render and initial client render don't differ
Not all life cycle functions are called on the serverside, mainly componentDidMount is not called. This indeed helps if you want to do some AJAX data fetching (which you only want to do on the client).
If you are using react-router you need to setup the serverside route matching
Here are some more details: React can be used on server side rendering. What does that mean?

Mixing Flux with in-component requests

I am building a react app with altjs as flux implementation. Currently I am making an image uploader component. The component takes an image, uploads it to the cloud and puts the url in the response in an input. The image url is sent within the form. It is also possible to skip the uploading process and type in the url manually.
The image upload process is as follows:
Component makes a request to the server, gets a signature.
The signature and the file is sent to the cloud storage and an url for the uploaded image is returned.
The url is set to the value of an input field.
I think this process will be easier if I make the requests in the component (in click handler function) without using flux. I do not need a flux store at all. I believe this is a better approach because this way I can put the component in any app and have it working. If I were to use flux, I would also need to transfer the action file and modify it a bit
It is generally said that every api request should go through flux as a good practice.
Is this a good practice or can I implement it in a better way using flux?
I think what you should do there is separate the concern of displaying the variables (image url), the button etc from the concern of the uploaded image and the signature you need as well.
Separated the components for having an image upload become very easy to handle and duplicate into almost any project, while the responsibility for uploading the image etc (which generally differs more per backing store / API ) is in a higher component. You can then choose per project if you choose to use flux for it or if you let the higher component execute with the data coming from the uploader and setting the props.
My suggestion would be to do the above with flux, but that's just because I feel really comfortable with the data flow in the whole application to be the same.

Resources