Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Backbone: React - Step 1

DZone's Guide to

Backbone: React - Step 1

The author got the green light to embark on an epic re-architecture refactor adventure. The refactor to end all refactors. The update will take us to infinity and beyond.

· Web Dev Zone
Free Resource

Learn how to build modern digital experience apps with Crafter CMS. Download this eBook now. Brought to you in partnership with Crafter Software

It’s happening! We’re moving Yup to React!

We’ve got 37,380 lines of Backbone and Handlebars JavaScript with architectural roots reaching as far back as 2013. Since then, there has been a pivot, some ebb and flow of different engineers, and more fundamental product changes than you can shake a stick at.

We’ve had a bug for the past 4 or 5 months that everyone on the team and every user has seen. We’ve even got in-the-wild video recordings of it, but nobody has been able to reproduce it reliably enough to even begin debugging it, let alone fix it.

After many months of poking and prodding and cajoling and covertly moving our codebase from ES5 to ES6, I got the green light to embark on an epic re-architecture refactor adventure. The refactor to end all refactors. The update will take us to infinity and beyond.

No pressure.

Of course, this refactoring can’t endanger the product roadmap, slow down the team, or cause any sort of inconvenience for the business.

That’s right. For the foreseeable future (possibly forever?), the React and Backbone parts of the code have to live together in harmony.

To get things started, we’re going to limit this Epic Refactor to a small, 7,100-line part of the codebase. That’s not terrifying at all! I mean, what could possibly go wrong?

Proof-of-concept for Views

Today, I built a quick proof-of-concept for how we can put large swaths of existing code into an otherwise React application. React is going to become the main part. Less React than Backbone at first, but React will be taking over the orchestrating of what renders when and how and where.

Right now, our app is built out of Backbone views like this:

class BackboneButton extends Backbone.View {
    constructor() {
        super();

        this.model = new Backbone.Model({
            N: 0
        });

        this.events = {
            "click button": "buttonClick"
        }

        this.template = Handlebars.compile('<button>Clicked {{N}} times</button>');
        this.listenTo(this.model, 'change', this.render);
    }

    render() {
        this.$el.html(this.template(this.model.attributes));
    }

    buttonClick() {
        const N = this.model.get('N');

        this.model.set({N: N+1});
    }
}

This is a typical Backbone pattern. You have a model that holds some state, a Handlebars template that puts variable values into HTML, an events hash, and a change listener. The user clicks a button and triggers a jQuery event, which calls the buttonClick callback. buttonClick updates the model, which triggers a change event. This triggers a component re-render, which inserts updated HTML into the page.

It’s reactive and almost functional. Pure beauty. Not so great in practice… it’s kind of a mess. Don’t believe me? Re-read the 2nd paragraph about Heisenbugs.

The first step to using these views in a React app is a wrapper that looks like this:

class ButtonWrapper extends React.Component {
    button = new BackboneButton();

    componentDidUpdate() {
        this._render();
    }

    componentDidMount() {
        this._render();
    }

    _render() {
        this.button.setElement(this.refs.anchor).render();
    }

    render() {
        return (
            <div>
                <p>Backbone Button:</p>
                <div className="button-anchor" ref="anchor" />
            </div>
        );
    }
}


Our React component that doesn’t do much: it renders a <div> element and uses Backbone’s setElement function to tell a Backbone view that this is where it should live.

This approach works great for inserting large isolated chunks of current stuff into an otherwise React app. Here’s a CodePen that proves this code works fine:

See the Pen React + Backbone, step 1 by Swizec Teller (@swizec) on CodePen.0

That was easy. I did it all before my 3rd cup of tea!

Now I’m stuck trying to make the data architecture inter-op. How do I build an overall unidirectional data flow architecture that works with these independent Backbone+Model views?

Hmmm…

Crafter is a modern CMS platform for building modern websites and content-rich digital experiences. Download this eBook now. Brought to you in partnership with Crafter Software.

Topics:
backbone ,isolated ,react ,refactor

Published at DZone with permission of Swizec Teller, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

THE DZONE NEWSLETTER

Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

X

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}