My humble beginnings with React.js

I was curious to find out what my first production usage of React to end users so I checked out the history of one particular project that I developed on and found out that my first React version was v0.4.1 ๐Ÿ™€

Screenshot of React v0.4.1 in a ZIP archive

The first React version was v0.3.0 was released on 2013-07-02 and v0.4.1 was released at the end of July, this definitely means that I was among the first early adopters of React ๐Ÿ˜‡

Unfortunately, I only stored the final compiled build artifacts, I started using version control 2 years later (hey, better late than never ๐Ÿ˜), so I don't have an exact source tree of what the code was.

Luckily the code is unminified/uncompressed1, so Iโ€™m able to piece together how I done front-end development 5 years ago and surprised myself along the way:

  1. Third-party vendor files are just copied to the workspace

    No usage of npm2 yet, and no easy way to track new versions by the authors
  2. All the JavaScript for the background/content/popup pages are written in separate big combined files

    Back then, concatenating multiple small files and combining into one big file was the usual practice, hope you donโ€™t mess up the load order...
  3. I didnโ€™t use JavaScript modules such as CommonJS or AMD, no Browserify/webpack usage yet
  4. No usage of Babel, not even sure if 6to5 was created yet. Lots of classical JavaScript and var usage
  5. No CSS preprocessor, no usage of Less/SASS
  6. As this project is a Chrome extension for Chrome 20+ (wow, that felt like brand new many years ago...), I didnโ€™t use jQuery and just directly access the browser DOM with vanilla JS
  7. However, I did use Zepto to easily animate fade effects
  8. Remember that React is originally developed and used at Facebook for small chunks on their regular server-rendered PHP/Hack pages, thatโ€™s how I originally used and bolted on React to this project too.

    Somehow some people think that React is for Single Page App (SPA) or you have to rewrite your entire app to use React, thatโ€™s definitely not the case
  9. Only 2 React components were created on my first version. I was still experimenting and evaluating React at that time, okay? ๐Ÿ˜€
  10. JSX was still relatively new, you have to use some JSXTransformer thingy. I chose not to use it, and used regular function calls instead
  11. Using React.createClass instead of ES6 classes
  12. Using React.DOM.* factories to generate elements, itโ€™s deprecated nowadays
  13. Doing silly things such as mutating this.props
  14. No type safety system is used, no usage of Flow/TypeScript, the best is a comment at the top telling which props that would be accepted
  15. Comma-first code style ๐Ÿคช
  16. IIRC no build tools are used yet, no Grunt or Gulp
  17. Code quality wasnโ€™t a priority/considered, no usage of JSLint/JSHint/JSCS/ESLint yet

Here is the code to give you a closer understanding of the past:

// React components
// props: text, rawText, className, noFlashYellow
var RadioTrackInfoText = React.createClass({
	 getInitialState: function() {
		if (!this.props.rawText) {
			this.props.rawText = this.props.text;
		}
	}
	,componentDidMount: function(rootNode) {
		if (this.props.rawText) {
			this.wordwrap(rootNode);
		}
	}
	,shouldComponentUpdate: function(nextProps, nextState) {
		if (!this.props.rawText) {
			this.props.rawText = this.props.text;
		}
		if (!nextProps.rawText) {
			nextProps.rawText = nextProps.text;
		}
		// If the text are the same, tell React to not update
		if (nextProps.rawText === this.props.rawText) {
			return false;
		}
		return true;
	}
	,componentDidUpdate: function(prevProps, prevState, rootNode) {
		if (this.props.rawText) {
			if (!this.props.noFlashYellow) {
				flashYellow(rootNode);
			}
			this.wordwrap(rootNode);
		}
	}
	,wordwrap: function(node) {
		if (needsEllipsis(this.props.rawText)) {
			addClass(node, 'hasEllipsis');
			node.title = this.props.rawText;
		} else {
			removeClass(node, 'hasEllipsis');
			node.title = '';
		}
	}
	,render: function() {
		return React.DOM.p({className: this.props.className}, this.props.text);
	}
});

// props: track, artist, event, event.title, is_live, text, noFlashYellow
var RadioTrackInfo = React.createClass({
	render: function() {
		if (this.props.text === STREAMOFFLINETEXT) {
			this.props.track = "Offline";
			this.props.artist = '';
		}

		var children = [];

		// Event info
		if (this.props.event || this.props.is_live) {
			var eventTitle = '';
			if (this.props.is_live) {
				eventTitle = "Live";
				if (this.props.event && this.props.event.title) {
					eventTitle = "Live: " + this.props.event.title;
				}
			} else {
				eventTitle = "On Air";
				if (this.props.event && this.props.event.title) {
					eventTitle = "On Air: " + this.props.event.title;
				}
			}

			children.push(RadioTrackInfoText({
				text: [
					 React.DOM.i({className:'icon-star'})
					,eventTitle
				]
				,rawText: eventTitle
				,className: 'eventInfo'
				,noFlashYellow: this.props.noFlashYellow
			}));
		}

		if (extStatus.settings.compact) {
			var text = this.props.track;
			if (text) {
				text += ' - ';
			}
			text += this.props.artist;
			if (this.props.text === STREAMOFFLINETEXT) {
				text = "Offline";
			}

			children.push(RadioTrackInfoText({text: text, noFlashYellow: this.props.noFlashYellow}));
		} else {
			children.push(RadioTrackInfoText({text: this.props.track, noFlashYellow: this.props.noFlashYellow}));
			children.push(RadioTrackInfoText({text: this.props.artist, noFlashYellow: this.props.noFlashYellow}));
		}

		return React.DOM.div(null, children);
	}
});

Even I felt like facepalming at some of the code/decisions there, oh well, learn from your past mistakes and see how your skills have improved over the years ๐Ÿ˜€

1 This is a Chrome extension project and I felt itโ€™s less important to minify files on downloadable software
2 I never used Bower