Uncaught Error: Objects are not valid as a React child

Situation: You create a class extending React.Component and want to declare it as a private variable; to update and call methods and then want to display it in the render method of the parent container. Straight forward:

this._myHappyClass = new HappyClass({someProperty: true});

Here we construct the class, which extends React.Component. Then we display it in the render method of the parent container:


public render(): React.ReactElement {

    return (
        <div>{this._myHappyClass}</div>
    ); 

}

And boom, screen blank, console displays error:

Uncaught Error: Objects are not valid as a React child (found: object 
with keys {props, context, refs, updater, state, updateDimensions}). If 
you meant to render a collection of children, use an array instead or 
wrap the object using createFragment(object) from the React add-ons. 
Check the render method of `HappyClass`.

I ran into this newbie problem and it took me a while to understand what was going on. The error seems to suggest the element I was trying to display for some reason isn’t a react child. It can’t display it. But my class is extending React.Component so what’s going on? I tried to cast it thinking that might be the issue, but still no luck. The solution is simple:

public render(): React.ReactElement { 

    return (
        {this._myHappyClass.render()}
    ); 

}

Just a small change, instead of putting the variable in the render method, call it’s render method instead, and this will return the React.Component. It makes sense right? If you just put the variable in there it’s trying to display a class, which is just an object, it’s just data. It’s the Render method that actually has anything to display.

Like I said, it’s a simple stupid problem but for a beginner in React this might help you save some time.

Advertisements

Warning: setState(…): Can only update a mounted or mounting component.

I guess you’ve got an event listener perhaps listening for a window resize or something like that and each time your render gets called you see this warning in the console?

The reason is because when you add “.bind(this)” to a method it actually returns a new one and because the previous listener never gets removed (the original isn’t mounted anymore) you get this warning.

To get around this add the following at the start of your code and then replace it in the event listener line:

this.updateDimensions = this.updateDimensions.bind(this);

SSL + localhost + Express + node.js + Certificate Fun!

So I was following a security chapter in a book by Evan Hahn called Express.js in Action (a very good read as it goes) and despite using the example code correctly and implementing what I expected to be a working SSL express node application I was met with Chrome’s dead face “no no no” page:

Screen Shot 2016-09-01 at 17.49.01

After a lot of searching and result-clicking and stack-overflow-scrolling I managed to find the two things that combined to fix the problem, and it’s nice and simple too. Read on!

Generate your self-signing certificate (we’re running on localhost and I trust myself) and key files (as Node likes them to be separate, not all combined). There’s some very good instructions on this here: https://certsimple.com/blog/localhost-ssl-fix .

At this point you should have your certificate.pem and a key.pem file. Next add these credentials when starting up your express application, and boom. Back in business.

var express = require("express");
var https = require("https");
var ms = require("ms");
var fs = require("fs");
var path = require("path");

// The path to where you exported your cert and key files.
var certificatePath = path.resolve(__dirname, "../.localhost-ssl");

// The specific location of the files.
var privateKey = fs.readFileSync(certificatePath + "/key.pem");
var certificate = fs.readFileSync(certificatePath + "/cert.pem");

// Combined to make a credentials object.
var credentials = {key: privateKey, cert: certificate};

var app = express();

app.get("/", function(request, response) {
 response.end("Hello, SSL World!");
});

// Create the https server like this and pass in the credentials.
var httpsServer = https.createServer(credentials, app);
httpsServer.listen(8443, function() {
 console.log("App started on port 8443");
});

And then with a little bit of luck and a cheeky smile you should get your output SSL message on the screen.

Hello, SSL World!