One Mixin to rule them all

or An intro to React Mixins

Codrin Iftimie
Front-end Development

--

Before continue reading:

Please note that blog post was about my initial encounter with React. Mixins are going away soon(check https://medium.com/@dan_abramov/mixins-are-dead-long-live-higher-order-components-94a0d2f9e750).

Also, holding state inside a mixin is hard to manage from outside of the component. Use props instead of state, for better separation of concerns.

Lately I've had the chance to get familiar with React, and got to use it in a project, along with Backbone. I’m really happy that I've got this chance, because it truly changed my perspective about the MVC design pattern. It’s good to use in small projects, but it may be tricky to maintain when scalling up. The Flux architecture is the future. But I won’t go deeper on that right now.

Small intro

React focuses on the V (Views) from the MVC pattern, and it can clearly replace any Views from any framework. The idea behind it, that it only changes the “dirty” nodes, it’s in my opinion something that was missing in the modern web apps. But this is not React is all about. It also relies on a virtual DOM, and Synthetic Events. These features make him kinda unique, although the guys from YUI have been playing with those synthetic events for a while. You may think that the React’s way of checking the dirty nodes and applying those changes is computational consuming, but compared to a total re-rendering of the app, I’d chose the first. Also since all the events are done on the top level of the DOM(window.document), it makes it fast since no events are really attached to the nodes, so you don’t have to worry about zombie views.
I've been struggling with a lot of out of the box UI frameworks to make them play along with Backbone. And until now my way of rendering Views, and their sub-views was pretty Neanderthal-ish. I would re-render the entire component if I was to add more subviews. This is where React comes in.

It is dead simple to use. You only have to know a components lifespan. It takes care of a lot of your problems. As Pete Hunt says it separates concerns. Also I've been obsessing with modulating everything. React Mixins helps a lot in creating reusable components. Let’s take a more hands on aproach.

A simple React component.

var Checkbox = React.createClass({
render: function(){
return (
<div>I will be a check box</div>
);
}
});

The idea behind a checkbox is a toggle. It has two states. On and off. Like a switch.
Let’s translate that into a mixin.

var Toggler = {
toggle: function(){
this.setState({
active: !this.state.active
});
};

Now we can add an event to the div we return in the Checkbox component. Normally the checkbox reacts (pun intended) on clicks. So we can add onClick={this.toggle}. Also we have to tell our component that it needs to use the Toggler mixin. Think of it as extending Backbone base classes (although it’s not really the same, you can’t overwrite methods afterwards).
To complete this component we will have to visually display the change. We can do that by adding an extra css class.

var className = “checkbox”;
if(this.state.active){
className += “ checked”;
}

Now add className={className} to the div and you are all set. You can also make it smarter to get a predefined initialActive from it’s props. So on getInitialState method we will add:

return {
active: this.props.initialActive || false;
}

But wait…

Lets say we have to make a dropdown menu. It kinda has the same principle. It’s still an on/off switch, but with some extra features. When clicking outside of it, it should close the one that is currently active.

var DropdownPattern = {
mixins: [Toggler],
_bindClickOutside: function(ev){
if(!ev.insideDropdown || ev.insideDropdown !== this){
this.setState({
active: false
});
}
},
onToggle: function(){
if(!this.state.active){
document.addEventListener("click", this._bindClickOutside);
} else {
document.removeEventListener("click", this._bindClickOutside);
}
}
}

We add this.onToggle && this.onToggle(); using the monkey patching technique to the toggle method inside the Toggler mixin, so you can reuse the this mixin.

If you want to go even more hardcore you can add this.props.onToggle && this.props.onToggle(); to the toggle method. This way we can do more things with the Checkbox component. We can execute functions on a higher parent level based on the checkboxes state. This way you separate the checkboxes logic from the application logic, and reuse this checkbox, in other cases. This also applies to Dropdown component.

The react class would look like

/** @jsx React.DOM */
var Dropdown = React.createClass({
mixins: [DropdownPattern],
prevent: function(ev){
ev.nativeEvent.insideDropdown = this;
ev.stopPropagation();
},
render: function(){
var className = “has-dropdown”;
if(this.state.active){
className += “ active”
}
return (
<div className={className} onClick={this.prevent}>
<div className=”drop-trigger” onClick={this.toggle}>
{this.state.active ? “I’m active” : “I’m inactive” }
</div>
<Dropmenu />
</div>
);
}
});

This is not all

The awesome thing of React is that we can combine those components. So we will create an multiple selector in part 2, and go deeper on rendering subcomponents.

--

--

Codrin Iftimie
Front-end Development

would like to save the web • movie enthusiast • accidentally brilliant at times • frontend technical lead @ bytex