A component is a self contained element made up of HTML, CSS and JavaScript. We can combine lots of components together to create user interfaces. @Jack_Franklin 3
The plan 1. The road to components ! 2. The theory of components " 3. The approaches and challenges of building good components ✅ 4. How to introduce components to your project/ product/app/site $ @Jack_Franklin 4
I'm using React today because it's what I know best. —But this talk is not framework specific and can apply to any form of components. —Whether we're talking Angular, Ember, Vue, web components, or any other system. @Jack_Franklin 24
You can focus in on one component and one component only, without fear of breaking other parts of the site. You and your brain can focus in on the problem area and shut everything else out. @Jack_Franklin 33
Your components should focus on presentations and interactions class SignUpToNewsletterForm extends Component { signUserUp() { // lots of // code here // to sign the user up // to your newsletter } render() { return (
Pull any standalone logic out of your components so you can focus on the presentation. import { signUserUp } from '...' class SignUpToNewsletterForm extends Component { signUserUp() { signUserUp(...) } render() { return (
And we need to be able to not show the item sentiment sometimes item={...} showBrand={true} showOldPriceBeforeSale={true} showSentiment={false} /> ! Job done... @Jack_Franklin 46
For some items we want to show the brand instead of the name item={...} showBrand={true} showBrandInsteadOfName={true} showOldPriceBeforeSale={true} showSentiment={false} /> ! Job done... @Jack_Franklin 47
! item={...} showBrand={false} showBrandInsteadOfName={true} showOldPriceBeforeSale={true} showSentiment={false} /> Good luck understanding all these options in six months time... @Jack_Franklin 48
You will constantly play configurability off against maintainability. You as a developer and as a team will need to come up with a set of rules that suit you. @Jack_Franklin 50
1. Define our CSS as normal. 2. Import our CSS (with a build tool like Webpack in the middle). 3. Use the classnames as generated at build time. @Jack_Franklin 61
It's up to your team to decide what's best for you and your project There are many different solutions and many different libraries; experiment with a few and pick the ones that works best :) @Jack_Franklin 66
Components are cheap, but not free —You pay in maintenance; more code and UI to maintain —You pay in complexity; another component that exists in your application —You pay in communication; this component will have to talk to others to get data @Jack_Franklin 69
But how to know when a component is too big? —How many lines of code is it? —How many different HTML elements are there? —How hard is this file to understand? —Does the name have (or should have) an And in it? ItemNameAndPrice. @Jack_Franklin 71
Similarities Differences The icons Slight visual variations The like/dislike logic They are displayed next to each other Basically everything is the same but no the designer knows best 3 3 you should discuss if the variations make sense, but I guarantee you that they will at least some of the time @Jack_Franklin 74
The key here is to explicitly allow just a few And you can apply CSS classes accordingly. .itemSentiment { ... } .itemSentimentVariantFadingIcons { ... } @Jack_Franklin 77
A good way to figure out if you're sticking to this is this: Could you take a brand new project, and place your component into it, with no other set up required? @Jack_Franklin 81
Some of your components will have to talk to the rest of your application. The trick is minimising how many and coming up with a structure to it. Don't allow any component to implicitly rely on some data. @Jack_Franklin 83
3 approaches —Components fetch data from your server via an API call —Components are given data from the server when it renders the HTML —Components parse data left for them in script tags @Jack_Franklin 85
APIs 1. Component initially renders a loading spinner (or nothing) 2. Component fetches from /your/api/some- endpoint.json 3. Component updates to show the data it has. 4. Component updates to show an error if anything went wrong. @Jack_Franklin 86
APIs ✅ ❌ Ensures we always have the most up to date data Adds extra loading state Easy to re-fetch the data if we need to Introduces chance of error Component is network dependent Component will be slower to show data to the user @Jack_Franklin 87
Data from server ✅ ❌ We get the data immediately from our server Data might be out of date if the user has performed an action since rendering Fewer states to worry about (no loading or error) Creates long strings of JSON in HTML @Jack_Franklin 90
Write a small util around your global config import { getConfigValue } from 'lib/global-config' const userIsLoggedIn = getConfigValue('user.authenticated', false) @Jack_Franklin 92
✅ ❌ Useful only for data that needs to be globally available Can lead to a huge set of config if used too much. A good way of setting data that can be accessed from anywhere on the site. Won't be updated if the data changes. @Jack_Franklin 93
Think carefully about all the different approaches and the ones that work best for each component individually. Type Situation APIs Good for data that changes and needs to be up to date Data from server Good for component specific data that won't change Global config Good for data that any component might need, and that won't change. @Jack_Franklin 94
Take Thread, for example —~5 years old, built as a server side Django app that renders HTML via templates to the client. —JavaScript is layered on top via plain old JavaScript and jQuery. —We now have ~50 components (give or take) and that number is going up all the time. @Jack_Franklin 99
In our JavaScript: import ThreadItemCard from './components/item-card.jsx' document.registerReact('thread-item-card', ThreadItemCard) In our server's templates:
We can introduce React and our component system without having to rewrite a lot of functionality that we already have on the server. And when we don't need JavaScript, we can still just render HTML and CSS via our server (!) ! @Jack_Franklin 103
Yes, all your components should be written using the same set of tools and techniques. But launching one that's built differently to learn about something provides a lot of value. @Jack_Franklin 114
To sum up... —Keep your components small and be wary of too much configuration —Beware anything that breaks the black box abstraction —Prefer explicit code over implicit knowledge of how your components interact —We're all figuring this out together, as we go. @Jack_Franklin 116