That fresh inline style

React is cool.

I know- React is so 2016- but I’m generally late to the party anyway.  I’d read good things, but hadn’t had a chance to use it in an official project (you know, the ones that pay real money).  So I started a side project using React JS.

Generally, it seems more modular than Angular 2.  When working on an Angular 2 (which I love) app, the approach is usually “Angular all the things”.  You are going to make a single page app.  It is going to use the router and Typescript and so on.  Very nice to have your decisions made for you.

With React, I have a bit more flexibility- but have to make some more decisions.  I can use it just to create some reusable UI components (working on a React based form for my static main website now).  Or I can integrate with a router and create a full blown single page app.  I wanted to test everything, so for the side project (a collaborative event creation and commenting app for scheduling our weekly beer-drinking night) I’m integrating react-router and going full-blown SPA (single page app- without all the typing).

This post, however, is about a trap I fell into with styling the app.  I fall back to the OG Javascript days when getting going with a new framework- and it can lead to trouble (see post from a while ago about me trying to manipulate the DOM directly in Angular).  So, when I wanted to use JS to dynamically offset a static header, I tried to getElementById and failed miserably.

React (and Angular) has lifecycle hook methods.  When your view is loaded and the DOM is ready, componentDidMount fires.  It seemed like a good place to add my little function to get the header element height (which will depend on the width of the user’s viewport) and add that much padding (plus a little breathing room) to the main wrapper.

setHeader() {
    const header = document.querySelector('#header');
    const wrapper = document.querySelector('#content-wrapper');
    //have to make sure header exists or error
    if(header) {
        wrapper.style.paddingTop = `${header.clientHeight + 16}px`;
    }
}

Please note: the above is not exact- that version of the function is long gone, but should give you the idea.

And it did fire properly in the lifecycle hook.  But the height of the header wouldn’t always change.  Turns out- in React (like in Angular), directly manipulating the DOM is a Bad Idea.  I haven’t dug too deeply into this, though I would guess it has something to do with the diffing/shadow DOM aspect.  But there is a good and easy fix.

Don’t manipulate the DOM directly.  Part of the beauty of these front end frameworks is that you can dynamically set styles.  Some developers set all their styles directly in their jsx.  So, instead of the above function, I used this

//call inside componentDidMount so the DOM is ready
setHeader() {
    const header = document.querySelector('#header');

    //have to make sure header exists or error
    if(header) {
        this.headerHeight = header.clientHeight;
    }
}

And in the jsx, set the style’s paddingTop attribute to the end value of this.headerHeight.  I would display it here, but for some reason WordPress won’t let me show html tags.  Sorry!  But the moral stands- this method works.  Knowing the native JS DOM manipulation methods is very useful, but it can help to forget them sometimes when using a front end framework.

Also, if anyone knows why html tags cause such trouble, let me know!  I tried both the <code> and <pre> tags, but html just comes out blank (works with other kinds of code it seems).

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s