Beyond the WAT
Why Component Design Still Matters
Becca Nelson • @beccaliz • becca.is

beccaliz
👩💻 The Mom Project
🏡 Chicago, IL USA
About Me

💜

beccaliz
component design
a11y

beccaliz

beccaliz
As I started working on the front-end more and more, there was this subtle attitude shift.

beccaliz

Have you ever tried using the builder pattern?

beccaliz


Great job working on the frontend! I think you should develop your skills more so you can be a strong contributor on the backend too!

beccaliz



beccaliz






beccaliz
Backend development is “hard and scary” while frontend development is just the pretty interface on top.



beccaliz
JavaScript has been a pretty historically unruly language.

beccaliz
> [] + []
""
> [] + {}
"[object Object]"
> {} + []
0

beccaliz


beccaliz


















beccaliz
It’s no longer just a necessary evil for building pretty UIs that we can pawn off on our junior engineers.

beccaliz
Component Design
What it looks like
Why it matters

beccaliz
Framework-specific design patterns
Overarching guiding principles
Framework-specific design patterns

beccaliz
As JavaScript engineers in 2019, what does it mean to design good components?

beccaliz
1. Accessibility
2. Scalability
3. Single Reponsibility
4. Testability

beccaliz
Accessibility

beccaliz
⚠️ Disclaimer

beccaliz
Semantic HTML
-
Using the most appropriate HTML tags for your content
-
Using HTML in a way that a user could navigate and understand the hierarchy of your site by using HTML alone.

beccaliz
Heading tags
Should be used in order
Should not be used to re-size content

beccaliz
<h1>Most important!</h1>
<h2>Second most important!</h2>
<h3>Third most important!</h3>

beccaliz
Most important!
Second most important!
Third most important!

beccaliz
<div className="content">
<button onClick={() => doSomething()}>
Click me!
</button>
<a href="/my/route">Go home</a>
</div>

beccaliz
<div onClick={() => doSomething()}>
// Content
</div>
❌

beccaliz
<i className="icon-email" title="Email me!"/>

beccaliz
-
Keyboard navigation
-
Color contrast
-
Font size / scaling

beccaliz
a11y Linter
Auditing Tools
http://a11yproject.com/resources

beccaliz
Scalability

beccaliz



beccaliz


beccaliz
No matter whether you are using dynamic or static types, no matter whether you are writing for the web or for the server...

beccaliz
Scalability is hard.

beccaliz
Because of people.

beccaliz
Bigger products = bigger teams.

beccaliz
With bigger teams, the more we need to be explicit about the choices we are making and why we are making them.


beccaliz
Single Responsibility

beccaliz
What does it mean for a component to be single responsibility?

beccaliz
It does only one thing.

beccaliz

<div className="card">
<div className="card__header">
<img className="card__image" src="/image"/>
Some header content
</div>
<div className="card__body">
Some body content
</div>
<button
className="card__toggle"
onClick={() => toggle()}
/>
</Card>

beccaliz
Single responsibility = testability & reusability

beccaliz
We can use naming to make it explicit that certain components belong together.

beccaliz
<Card>
<CardHeader>
<CardImage src="/image"/>
Some header content
</CardHeader>
<CardBody>
Some body content
</CardBody>
</Card>

beccaliz
<Card>
<Card.Header>
<Card.Image src="/image"/>
Some header content
</Card.Header>
<Card.Body>
Some body content
</Card.Body>
</Card>


beccaliz
Testability
class UserProfile extends React.Component {
state = {
profile: undefined
};
componentDidMount() {
fetch("/my/profile").then(response => {
this.setState({
profile: response.json()
});
});
}
render() {
if (this.state.profile) {
return (
<div className="user-profile">
<div>Name: {this.state.profile.name}</div>
<div>Email: {this.state.profile.email}</div>
</div>
);
}
}
}
global.fetch.mockImplementation(() => {
return new Promise(resolve => {
resolve({
ok: true,
json: () => {
return {
name: "Jane Smith",
email: "jane@example.com"
}
}
});
});
});
class UserProfile extends React.Component {
state = {
profile: undefined,
completed: false,
};
componentDidMount() {
...
}
render() {
if (!this.state.completed) {
return (
<a href="/profile/edit">Complete your profile!</a>
)
}
else if (this.state.profile) {
return (
<div className="user-profile">
<div>Name: {this.state.profile.name}</div>
<div>Email: {this.state.profile.email}</div>
</div>
);
}
}
}
class UserProfile extends React.Component {
state = {
profile: undefined,
completed: false,
};
componentDidMount() {
...
}
render() {
if (!this.state.completed) {
return (
<a href="/profile/edit">Complete your profile!</a>
)
}
else if (this.state.profile) {
return (
<div className="user-profile">
<div>Name: {this.state.profile.name}</div>
<div>Email: {this.state.profile.email}</div>
</div>
);
}
}
}

beccaliz


beccaliz
Displaying Information
Interacting with outside world

beccaliz
Another note on testing...

beccaliz
Testing is a core tenet of good component design.

beccaliz
Our tests can be living documentation of our components and how they are intended to work.

beccaliz
Why does this matter?

beccaliz


beccaliz
🤩 🥳 👏 💯

beccaliz

beccaliz
Put yourselves in the shoes of a user, or a new teammate, or even yourself a year from now.

beccaliz
What are the things that would help you to understand what is going on?

beccaliz
What are the things that would help you to feel empowered to contribute without re-inventing the wheel or breaking existing functionality?

beccaliz

beccaliz
Thank you!!
Beyond the WAT: Why Component Design Still Matters
By Becca Nelson
Beyond the WAT: Why Component Design Still Matters
n the tech community, sometimes JavaScript gets a bad rap. From its type inconsistencies to its 90’s-era syntax to its status as a “less important” programming language, JavaScript is sometimes seen as a necessary evil that should be avoided whenever possible. But as components become more complicated and accessible user interfaces become a bare minimum requirement, the work we do with this language is more important than ever. Let’s talk about good component design—what it looks like and why it matters.
- 1,412