800 React fans came to Berlin for in-depth talks and hands-on workshops by 24+ speakers on all things puzzling React developers minds, be it architecture, Design Systems or styling in React. Check my takeaways from the conference.

Why and how to use React Hooks?

The conference started with Ken Wheeler discussing his favorite new features coming to React (memo, lazy, createContext, suspense) and dedicating most of the time to Hooks.

React Hooks solve a wide variety of seemingly unconnected problems, in particular:

It’s hard to reuse stateful logic between components

Complex components become hard to understand

Hooks let you use more of React’s features without classes and allow to write less code, but most of all, reorganize code to make it more readable.

Ken showed us Hooks in actions using a music mixer as a real-world application example. Which was very entertaining:

How to improve code reuse in React applications?

Right after Ken’s talk, the stage entered Forbes Lindsay. He presented how combining the context API and render props gives you unprecedented power to cleanly reuse code across components.

The presentation was very similar to the one React Alicante, so I include it here as a placeholder until the React Day Berlin presentation are published on YouTube:

Powering Code Reuse with Context and Render Props summary:

Functions being first-class values means we can use them as parameters to enable more flexible code re-use

Using functions as parameters allows highly customizable shared components, complete with state and lifecycle hooks.

React Context lets you share state across the tree of your applications

Context still uses the React tree. This means it works with server-side rendering and you can safely use it in parts of your app, as well as using it as a whole app solution.

How to organize your React application architecture?

Oleg Isonen come with insights from webflow on building complex applications. He presented goals and set of principles that help you to define the boundaries of feature-driven architecture.

Goals:

Discoverability

Work parallelization

Controlling shared abstractions

Refactoring

AB Tests

Integration Tests

Principles:

Principle #1: Decentralization

In Oleg's definition monolith is when the entire codebase is heavily interconnected. He brought as example popular default structure for React applications with a single folder for components, containers, actionCreators, and reducers. This way single feature is spread all over and everything is interconnected.

As a solution, Oleg presented feature driven architecture where a feature is a self-contained user-facing reusable complex building block. In a way, code matches UI here. It is more high-level abstraction than a component, but smaller than pages or screens.

Principle #2: Explicit Sharing

There is an untold thought about shared abstractions: you can not trust even 100% unit test coverage - it can still break. Static types help a lot but still won't discover all problems.

Oleg proposed a methodology to decide when to share code:

Needed in at least 2 places

Not-trivial logic

Low frequency of change

Other advice included:

Use pure functions utilities

Write more tests

Carefully design the interfaces

Do more detailed code reviews

Principle #3: Co-location

On top of the file system colocation mentioned in the first principle - Decentralization - you should also put together styles, images, tests, anything we can. This also applies to Redux store structure (i.e. with Ducks: Redux Reducer Bundles).

With React Hooks we can now better colocate state management code:

Principle #4: Decoupling & isolation

Here we have to use common sense, but offered some principles you can apply:

A feature should not depend on other features

A page/screen should not depend on other pages/screens

A shared abstraction should not depend on either

Learn those to React tools to decouple your logic:

Render prop

Element as prop

Component as prop

Context API

Principle #5: Disposability

Do not optimize for modification, unless you can predict the future. Instead, optimize for ease of removal, based on what you already know. At some point, everything is going to be a Mess so the only choice you have is to either refactor everything vs refactor isolated parts.

What problems does a design system solve?

Let’s start with what 2,000 CEO survey results show they want form developers the most:

A design system is a collection of reusable components, guided by clear standards, that can be assembled together to build any number of applications - Will Fanguy, Invision

Before you build a design system, you do design audit. The result can be detected a lot of inconsistency in design. But the worst thing is that designers and developers have most likely have wasted a lot of time by trying to optimize all those inconsistencies.

Secret #1 is Design systems are about productivity

You get consistency as a side effect.

Secret #2 The world is bigger than React

You have to plan for it. Use platform-agnostic data that visual data attributes.

Secret #3 A design system is a dependency

Change management in the design system is challenging:

Depreciate gradually and communicate in the code and docs

Define and test (ideally automate) the critical path in your apps

Use canary builds to release in a shared env before production

The real cost of software is not the initial development, but maintenance over time. Monica Lent presented two models for scaling a design system:

Secret #4 Collaboration is key to long-term quality

Organize in a way that scales.

Secret #5 Design systems are about people

People success is the system's success. Key KPIs for design system are Speed, Quality, Ease of Contribution and Completeness.

Monica showed team scored hight their Circuit UI Design System which is build using docz The cost of the design system can be significant. Docz is appropriate for a design system or just simple project documentation. I would recommend considering Storybook as it can help you with Automated Visual Testing.

How to write good tests?

Jack Franklin in Tip Top Testing in JavaScript presented generic tips on how to write good tests.

You should be able to look at a single it test and know everything

Jack started with giving generic tips on tests structure:

it(‘clearly says what is being tested’, () => { // 1. Setup // 2. Invoke the code under test // 3. Assert on the results of step 2. })

Mocks are an essential tool in a developers’ testing toolkit

Tests should have no external dependencies. If your tests can fail without any of the code you’re testing changing, your test is not properly isolated. An unrelated code should not break your tests. This is a huge cause of concussion and frustration in large code bases. Use mocks. They are an essential tool in a developers’ testing toolkit.

Use regular refactoring and code techniques within test files

It’s important that test data that resembles your real data. Use functions to create data for tests. There are libraries aka data factories.

One idea that comes to my mind after this presentation is that you should use data creation functions and test their output against real data dumps - aka test your test data from the beginning of Jacks presentation.

Check out my article on Testing React Components Best Practices. It covers tests refactoring patters in more details.

Avoid brittle tests: test the public contract, not internal details

When I change the code I have to change the tests as well, so all tests do is double the amount of work I have.

When you write new tests, check that they fail

If you write a test and it passes the first time, try to break it. Use small feedback loops. Red, Green, Refactor.

Using Enzyme or react-testing-library does not matter as long as you write good tests following the above rules and you test like a user in a browser.

BEM? SASS? CSS Modules? Styled components? What is best for styling?

Sara Vieira talked about different approaches to styling. She presented the pros and cons of each of ways:

Plain old CSS and BEM

Pros:

Easy to set up

Framework/Library agnostic

Rigid Structure

Cons:

Naming is hard

REALLY HARD

I can’t memorize all those rules fam…

Preprocessors

Pros:

Nesting is dope

Server site renderer

Combine with BEM

Cons:

More dependencies to handle (before CRA2)

Not componentized by default

No JS magic in your CSS

CSS modules

Pros:

Use all the new CSS things

Server site renderer

More component based so it’s more maintainable

Cons:

Unreadable class names

Needs to be paired with PostCSS or Pre Processors for a good experience

CSS in JS

Pros:

Conditionals in CSS

No more specificity problem

Naming things is not so hard anymore

Cons:

It forces you to think about CSS in a different way which may take longer to get comfortable

Depending on the CSS-in-JS you may have to use object-based CSS

If your app is SSR and your styles are not you will get initial flash

The conclusion of the presentation is that styling is hard. No one is wrong. No one is right. It all depends on what you use it.

I liked this presentation because this topic is really often brought in projects. Now I have a clear answer: use what makes you code faster and better.

React Day Berlin 2018 Summary

I would like to end this post with a tweet from “Navigating the Hype-Driven Frontend Development Word Without Going Insane” presentation by Kitze

191 replies to post on making choices in the JavaScript world :-) This is insane. Don't get yourself to the Fear Of Missing Out. It's just a side-effect of wrong priorities.

Focus on what is really important: users getting value and the project sponsor making some money. Recognize breaking points in technology adoption. Consider how easy it is to transition to it? Is now the right time? Do you really need it?

We really need more of conferences like React Day Berlin and we need a healthy approach to what we learn there.