V
V
vilix2016-01-18 02:57:30
Node.js
vilix, 2016-01-18 02:57:30

How to use server and client rendering at the same time in reactjs?

I have been trying for two days to solve the problem that happened to me when customizing this tutorial for my task, and in impotence I decided to ask here. The tutorial itself turned out without problems.
My component simply outputs data from the database in the form of a list, and at intervals loads new data via API - an elementary task that I implemented using react, but I wanted to render the component first on the server. And this is the essence of the problem, on the server I successfully render my react component passing data from the database to it, but on the client the data from the database is obtained after a while (until the API request passes), and it turns out that everything on my page is first displayed as necessary, then everything disappears for a fraction of a second (the render react on the client fires with empty state and props) and then when the response from the server comes to the client, everything is fine again.
And I just can’t figure out how to make react not render anything until it receives data from the server, and if these data match, then react should not render anything, the checksum will match, but at the very beginning, when there is no answer yet, the checksum naturally always does not match and the react on the client renders an empty element.
The logic seems to be sound: react on the server renders a list with data, react on the client waits for a response from the server to the get api request, and if the data differs, react changes the DOM.
But the whole problem is that the react always calls render at the very beginning, and at the very beginning the response from the server, of course, has not yet come. For example, you can send a get request to componentWillMount, but I don’t know how to make init render wait for this request to complete.
Thanks in advance for your answers, I hope I was able to express the essence of my problem with grief in half.
UPD: As a possible solution, it is to put my data on the page as json, then I can use the same props to initialize on the client as on the server, but isn't that clumsy?

Answer the question

In order to leave comments, you need to log in

2 answer(s)
V
vilix, 2016-01-18
@vilix

I found another solution for myself, due to the fact that I was haunted by the idea that the data is already on the prerender page and I need to duplicate it in the script. And I thought why not parse them directly from the HTML in getInitialState and it works.
But I think this solution is not suitable for everything, the pitfalls that I see are:
1. Firstly, it is necessary to implement the logic of the parsing itself, which may not always be trivial
2. If the amount of data is large, parsing can take a significant amount of time and at this time the component will not respond
3. It is necessary to store all the necessary invisible data for the user in the tag attributes all the time, and not only during server pre-rendering, so that the checksum of markups matches.
In the end, I got something like this (maybe it will be useful to someone):

getInitialState: function () {
    if (!isNode) {
      var data = [];
      $('#dataId').map(function(key, element) {
        var id = element.getAttribute('data-reactid');
        id = id.substring(id.indexOf('$')+1);
        var title = element.innerHTML;
        data.push({id: id, title: title})
      });
      return {data: data}
    }
    return {};
  },

Please write in the comments if I missed something important in the cons of this approach or, on the contrary, thought up something extra.

A
Anton, 2016-01-18
@SPAHI4

I advise you to look at https://github.com/goatslacker/iso

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question