June Hackday - Team KASX (Part 1)
React JS Melbourne - August Meetup
React JS Melbourne - February Meetup
Recently we hosted the quarterly React Meetup at Kogan HQ!
React JS Melbourne - June Meetup & Video
React March Meetup Recap
Last night we hosted the largest-ever React Melbourne Meetup!
Talks included:
- Short intro to React & Flux - Nick Farrell
- React migration methods, made easy - Me
- Converting Stateful components to Redux - Cam Jackson
- React + Typescript - Basarat Ali Syded
There was a great range of content and complexity across the talks, with some good discussions during the breaks.
I gave an overview of how we have iteratively converted Kogan.com to React, in the most non-breaking way possible.
Slides are embedded below, or available here.
Interested?
If you'd like to learn more about this we are hiring!
Or if you are interested in speaking at the next Meetup, get in touch. You may even get a free hat.
Template Illogic: from Django and Handlebars to React
When the current incarnation of Kogan.com was developed, most pages were rendered server-side with Django templates; client-side rendering used Handlebars.js templates.
As well as the effort (and inevitable mismatching content bugs!) caused by maintaining two templates for some parts of the site, the syntax often became awkward and cumbersome. As Kogan.com expanded with new features and into new markets, both templates grew more complex.
For example, if you wanted a page to use "Zip code" in one country and "Postcode" in the others, one could do this:
{% if country.name == 'United States' %} Zip code {% else %} Postcode {% endif %}
This is just the "obvious" way to choose which word to use; there are more appropriate ways of doing this (using the translation features) as well as less appropriate methods:
{{ country.name == 'United States'|yesno:"Zip code,Postcode" }}
Unfortunately this isn't so straightforward in Handlebars, as there are no operators to allow comparison of variables - control flow structures such as if/else will only operate directly on the boolean value of a variable.
This is a deliberate design decision by Handlebars to enforce the separation between logic and presentation. Mustache (the templating language Handlebars is based on) is even stricter - there are no explicit control flow statements other than loops.
Therefore, it is necessary to pass a value which can be treated as a boolean to Handlebars:
{{#if country.isUSA}} Zip code {{else}} Postcode {{/if}}
Or just take all the logic out of the template and pass the content itself:
{{ country.prefixOfTermUsedInThisCountryForPostalCodesIncludingSpaceCharacterIfSeparateWord }}code
Handlebars can be extended with arbitrary functions, so some such as #ifEquals
have been written to allow equality comparison. Other helpers such as #ifCond
can work with any conditional operators, but they have no matching else statement, so it is necessary to use two opposite operators:
{{#ifCond country.name '==' 'United States'}} Zip code {{/ifCond}} {{#ifCond country.name '!=' 'United States'}} Postcode {{/ifCond}}
One of the benefits of our migration to React.js is the melding of Javascript with the template system into the creature known as JSX.
Although at first glance this tramples all over the separation of logic and presentation, the logic is restricted to only presentation-related decisions due to the way React enforces rendering from a meticulously defined state.
Keeping the front end code and the template within the same file also means it is easier to figure out what is going on - and much easier for programmers who have less front-end experience to use. Compared to our previous hierarchy of .js and .handlebars files, we have found React is a more readable and maintainable solution for the whole team - most of the time:
${storeCode === 'us' ? 'Zip ' : 'Post'}code
React Meetup - April 2015
Yesterday we hosted the second React Meetup in Melbourne, what a great turn out! It was great to see such a big community for a new technology.
Here is a link to the talk Michael and I did: