Killing Switch Statements in React with the Strategy Pattern

I saw this article about building multi-step forms in React recently - and although it's a very well-written and organised article, I was concerned about the use of the switch statement in the render() method of a React component here:

// file: Registration.jsx

var React         = require('react')
var AccountFields = require('./AccountFields')
var SurveyFields  = require('./SurveyFields')
var Confirmation  = require('./Confirmation')
var Success       = require('./Success')

var Registration = React.createClass({
	getInitialState: function() {
		return {
			step: 1
		}
	},

	render: function() {
		switch (this.state.step) {
			case 1:
				return <AccountFields />
			case 2:
				return <SurveyFields />
			case 3:
				return <Confirmation />
			case 4:
				return <Success />
		}
	}
}

module.exports = Registration

It's entirely possible that the writer of this article intended the switch statement here as example, or pseudo-code. However, as proven by reams of Stack Overflow questions, many programmers are quite happy to copy-paste code directly out of internet tutorials and into their production software. For this reason, I feel it's necessary to bring design patterns to the table when talking about code on the internet.

What's wrong with the switch statement?

I'm of the opinion that the presence of a switch statement, or an if-else, is a very pungent code smell. Why? A programmer who uses an if-else or a nested conditional is attempting to model a functional problem in an imperative style.

Anything that could be represented by a flow chart, like our conditional rendering of different React components in the prior example, should be approached as a functional problem. This is because every "step" in a flow chart is the representation of a function, or an "operation".

Anything that could be represented as a JSON string or an XML document (or a POCO, POJO, whatever your language calls them) should be approached through traditional object-oriented, imperative means. The two styles, like oil and water, don't mix very well.

Ever seen arrowhead code? If so, you know what happens when you try to mix the styles. Brittle code. Crossed eyes. Missed deadlines. Bad stuff.

Fixing the switch in the example

Yeah? If you're so smart, what do you use instead of a switch statement?

Answer: The Strategy Pattern

Here's a robust design pattern that can completely circumvent the need for a switch statement in most everyday cases.

If you can't immediately see the benefits of the strategy pattern from this pointless, contrived example, then try it next time you have to deal with some hardcore conditional logic. You'll be impressed.

Applying the strategy pattern to a React component

I'm not going to make an assumption about how you manage your state here, but I'm going to present it as a plain old JavaScript object to make it easier to see what I'm getting at.

Do you see how much clearer the component is? All we're doing is calling state.ActiveComponent, which is actually a function that generates React elements for us.

All you have to do, dear reader, is figure out how to iterate the index of the page array and apply the changes to your state, which I couldn't do without getting too opinionated about your state management framework.

Hopefully I've now provided you with everything you need to nuke switch statements in your code and start filling the internet with more maintainable, readable code.