Interactive JavaScript exercises made with React

A while ago I’ve composed and published a list of recursion exercises in JavaScript. The idea is simple: make all the tests green. But the point is to figure out the solution in recursive style. Recursion sometimes can be more elegant and much shorter solution to the problem, while iterative approach might lead to a pile of unreadable code.

I have those exercises in recursion-exercises repo, it’s intended to run in Node. But I also wanted them to work in the browser, so it’s much faster to start play with. Interactive exercises are available online, here, try it yourself and submit a pull request with more challenges if you have some.

So here’s a short blog post on how to create your own tiny JS Bin using React. I’ve started with CodeMirror, because it’s quite good editor, with many addons and themes, and it’s very easy to integrate with React.

React 0.14.0 code here. CodeMirror package can be installed from NPM.

const Codemirror = React.createClass({

componentDidMount() {

this.cm = CM(this.refs.editor, {
value: this.props.defaultValue,
mode: 'javascript'
});

this.cm.on('change', (cm) => {

this.props.onChange(cm.getValue());
});
},
componentWillUnmount() {

Reflect.deleteProperty(this, 'cm');
},
render() {

return <div ref='editor' />
}
});

Nothing fancy here, except probably Reflect.deleteProperty(this, 'cm'). That’s a part of ES2015 Reflection API and what it does here is removing property cm from this object, very much like delete keyword, but function call feels better. Reflection API takes some well known JS operations and makes them to return meaningful data as a result of that operation. But let’s get back to the code.

The above component can be wrapped with a stateful one, which is responsible for providing default code for the editor. It can also save code into localStorage and load it back, so you never loose your code after page reload. Along with the editor component, there’s another component, which executes code as a test and renders result of that test. Basically what it does it just eval. But I wanted to take an advantage of ES2015, because it makes writing recursion more fun and code looks cleaner. So I took browser build of Babel.

eval(babel.transform(code, { stage: 0 }).code);

Don’t forget to wrap this into try…catch to intercept either evaluation or compilation errors and render them later. But you still may get errors 😅

The thing is that the code should be evaluated in the sandbox, so it doesn’t interfere with the main process where all of your application code is running. For example: in the very first exercise you need to implement a function with the name of sum. So if you try to execute the test without that function, it’s going to be an error.

sum is not defined

But in Safari this error was different.

sum is not a function. (In 'sum()', 'sum' is an instance of HTMLDivElement)

WAT? Turned out there was a DIV with ID of sum on the page, and IDs are global vars, WAT? You can read more about it here. That’s an example why you might want to have a sandbox. I made a small Web Worker and moved test execution code into it. That’s it.

Online exercises are here and the source is in the repo.