1
\$\begingroup\$

I'm trying to update my skillset by learning how to write isomorphic JavaScript applications. For my stack, I've chosen React and Express - no database yet.

The problem many people seem to face when it comes to writing these kinds of applications is getting data from the server to the client so the view can be rendered properly client-side. Apparently the best way to do this is to JSON encode the data and include that in the server-rendered page.

All of this is done and working, but I would really appreciate if somebody who knows what they're doing could weigh in on my techniques before I develop bad habits.

A working repository (very small) is available on GitHub, but I have included the relevant concerning code below.

To get the data to the client, I pass it down through React until it hits the base template, where it is encoded and included in an invisible element:

return this.isServer ? (
    <html>
        <head>
            <title>{ this.props.title || "Untitled" }</title>
            <link rel="stylesheet" href="/static/theme/style.scss"/>
        </head>
        <body>
            {
                //If data is to be passed into the view, encode it as JSON and insert it into a hidden element
                this.props.data &&
                    <x-data>
                        { new Buffer(JSON.stringify(this.props.data)).toString("base64") }
                    </x-data>
            }
            <h1>My Files</h1>
            <main>
                { this.props.children }
            </main>
            <script src="/static/js/bundle.js"></script>
        </body>
    </html>
) : this.props.children;

The application is rendered into the <main> element on the server, and if this code is running on the client, it is handled elsewhere, in my client entrypoint:

import App from "./views/index.jsx";

//Get data from server, which is passed down through the x-data element
//It is base64 encoded JSON
let props = {};
let xData = document.body.querySelector("x-data");
if (xData) {
    let json = JSON.parse(window.atob(xData.innerText));
    Object.assign(props, json);
}

//All pages will export an App class which renders the current page
ReactDOM.render(
    React.createElement(App, props),
    document.body.querySelector("main")
);

The App class is the base React component to render this specific page. I'm not sure how I'll work out having multiple pages in the future, but this is how I have it working now.

Am I following a proper design pattern, or have I invented some mutant hellspawn technique that should be vanquished with a quick rm -rf?

\$\endgroup\$
1
\$\begingroup\$

You can render your webpage on the server complete with all props/state in place and at client-side React will pick up from initial state when he founds markup already existing.

So write your components the normal way, query database (or what have you) for props and render on server using ReactDOMServer. Here's a little example.

(As far as I can tell, you're doing something similar in your repo, so this is probably late to the party :)

\$\endgroup\$
  • \$\begingroup\$ Thank you for the reply! I think I'm doing it correctly now, I just wanted to be sure :) \$\endgroup\$ – Scott Jan 10 '16 at 16:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.