This course has been updated! We now recommend you take the Intermediate React, v5 course.
Transcript from the "Running React in Node.js" Lesson
[00:00:00]
>> Brian Holt: So here's the thought process I need you work through in your head. We're gonna be running our React application in Node. So anything that references window doesn't work in Node, because window doesn't exist, right, it's not in a browser so you can't reference window. So for example, if I come in here to App.js, down here at the bottom, document, which is on window, doesn't exist.
[00:00:29] There´s no document in the Node setting. So we need to split this out for code that will only run in the browser, and then everything else will be run in Node, for the first time for the first render, right? Cuz what we're gonna to do now is, we are going to render our entire React application out to static HTML and serve that on the first request so that the user immediately sees something, right?
[00:00:52] The first render will already be done, and then React downloads, and bootstraps, and does all that kind of stuff. It will just take over the existing markup. This is called server-side rendering, or SSR often for short, or universal rendering, or isomorphic rendering, there's a bunch of dumb names for it.
[00:01:09] It's just taking React and rendering a node, it's not anything more fancy than that.
>> Brian Holt: I hate dumb computer science, stupid. Isomorphic, that's just the most pretentious thing I've ever heard. [LAUGH] So let's get into this. So I'm gonna come in here and I'm gonna create a new file here inside of, where do I put it?
[00:01:37]
>> Brian Holt: Actually, let's do this first. Inside of source, I'm gonna create a new file and I'm gonna call it, ClientApp.js. So inside ClientApp is where we're gonna do all of our browser stuff, so ClientApp will not be run inside of Node. So this will actually do the rendering to the DOM, and anything that you need, excuse me, anything that you need to do that's browser-specific can be done in here.
[00:02:03] And a good example of what that might be would be your analytics, right? You're not gonna fire analytics for the browser inside of Node, so this could be done here just fine. For our purposes, we're just going to import React from 'react';.
>> Brian Holt: import { render },
>> Brian Holt: Sorry, import { render } from 'react-dom'.
[00:02:31]
>> Brian Holt: And import the App from ' ./' App. And actually, we're not gonna use render here. We had been previously using render to render to the DOM, right, but we're actually gonna use something called hydrate.
>> Brian Holt: So what's different between hydrate and render? hydrate is different, because what hydrate does is it looks for existing markup to take over an existing application, whereas render is gonna say, this is blank, replace everything inside of there.
[00:03:01] This is new to React 16, previously it was render in both cases. So that's why we're gonna use hydrate now. So hydrate,
>> Brian Holt: (<App />, document.getElementById("root"));.
>> Brian Holt: So at ./App.
>> Brian Holt: And this will get us bootstrapped on the client, right? Now, this is going to be our entry point to the application, not App.
[00:03:45] App is gonna just be another component that exports a module. So we actually need to go into index.html. Here it says, script equals src="./App.js". We're actually gonna make this ClientApp.js, cuz this is now the entry point to our application.
>> Brian Holt: And if you remember, this is what Parcel's reading from to figure out where to start, so that's what that's important.
[00:04:19]
>> Brian Holt: Okay, so now I need you to go to App.js. Down here at the bottom we have this ReactDOM.render business down here. Not gonna do that anymore, I'm just gonna say, export default App;, and this will be pulled into ClientApp for the rendering process.
>> Brian Holt: So you can come up here as well and delete ReactDOM, cuz we're not using that anymore.
[00:04:55]
>> Brian Holt: Okay?
>> Brian Holt: One more thing that we have to do, let's go into Modal.js.
>> Brian Holt: This is where we're doing the portal rendering. We have a problem here, because inside of Modal we're referencing document again, right? So if we try and import Modal.js we're gonna crash the node, right?
[00:05:16] Because it's referencing document.getElementById(), so how are we gonna get around that?
>> Brian Holt: It's actually not too bad. We're gonna move this, not to the constructor but into componentDidMount().
>> Brian Holt: And rather than saying, const modal = that, we're gonna say, this.modalRoot = that.
>> Brian Holt: And this.modalRoot.appendChild(this.el). And again, this constructor still might be run inside of React.
[00:05:49] We don't want that to crash if you ever construct the Modal, so let's just move this from the constructor into componentDidMount() as well.
>> Brian Holt: Like that. And here, now this is just this, oops, excuse me, this.modalRoot. Now, why did this fix everything? Well, when is componentDidMount() run? When it actually enters the DOM for the first time.
[00:06:16] So if you think about it, it's never going to enter the DOM in Node, right? It's gonna go through the first render process but it doesn't ever actually enter the DOM, so anything that you do inside of componentDidMount(), you're guaranteed to be in the browser context. So anything you need to do browser-based, you can throw it into componentDidMount() and that's fine.