33 line React

Thoughts on reading through the hacker news response.

React

you pass in a function that takes state and returns a virtual DOM (just a tree of plain ol' js objects)

objects) it renders that virtual DOM as a real DOM in the browser

if you change the state, it runs the function again, this returns a new virtual DOM

it efficiently updates the real DOM so that it matches the new virtual DOM

In this post, I'm going to make the smallest React-like thing that can do the above. It's very mithril influenced.

Here are sample applications: calendar picker, snake that use the library.

Lots of the code looks pretty code-golfy - I promise I don't do stuff like this at work, neither should you :-)

Noughts and crosses

We're going to make this noughts and crosses game:

Now let's look at the code to this, you can also just view the page source if you want.

let currentPlayer = 'o' let winner = null const g = [['', '', ''], ['', '', ''], ['', '', '']] // grid const move = (value, i, j)=>{ // ... game logic goes here renderNoughts() } const Cell = (value, i, j)=>m('button.cell', {onclick: ()=>move(value, i, j)}, value ) const Noughts = ()=>m('', winner ? m('marquee', `winner: ${winner}`) : m('h3', `current player: ${currentPlayer}`), m('table', g.map( (row, i)=>m('tr', row.map( (value, j)=>m('td', {class: value}, Cell(value, i, j)))))), ) const renderNoughts = ()=>m.render( document.getElementById('noughts'), {children: [Noughts()]}, ) renderNoughts()

Cute, so what's going on?

First we defined some state:

let currentPlayer = 'o' let winner = null const g = [['', '', ''], ['', '', ''], ['', '', '']] // grid

These hold the state of our game, we will mutate them.

const move = (value, i, j){...}

This function makes a move in the game, it takes 'x' or 'o' along with 2 integer coordinates. It will mutate all the state variables to reflect the new state of the game. After that, it calls renderNoughts() , this is a call to rerender the game - but we'll come back to that.

Next we define the functions that return virtual DOMs, Noughts and Cell .

The m(...) calls take:

a tag name (eg. 'tr' ), with . -separated class names

), with -separated class names (optionally) a {string: any} object containing all the attributes to attach to the DOM node

object containing all the attributes to attach to the DOM node an arbitrarily nested list of children - these are other virtual DOM nodes or strings of text

Noughts()

{ tag: 'div', attrs: {}, classes: [], children: [ { tag: 'h3', attrs: {}, classes: [], children: [ 'current player: x' ] }, { tag: 'table', attrs: {}, classes: [], children: [ { tag: 'tr', attrs: {}, classes: [], children: [ ...

Next we make the function renderNoughts() , when you call it, it will call our Noughts function, and attempt to efficiently render the resulting virtual DOM onto document.getElementById('noughts')

How does m work?

Here's the source with and without comments.