by
Travis Waith-Mair
@travisWaithMair
non-traditional.dev
Stop Writing Reusable React Components
MySudo
We're hiring!!
Components have changed everything
Benefits of Components
- Breakdown and isolate UI into easier to reason parts
- Components are testable
- Code Re-use
Benefits of Components
- Breakdown and isolate UI into easier to reason parts
- Components are testable
- Code Re-use
Thinking in React
A Real Life Example
My First Non-Trivial React App
Landing Page Hero
export function Hero(){
return (
<header className='hero'>
<h1>Assimilation Point</h1>
<p>The point of assimilation</p>
</header>
);
}
V2
export function Hero({title, subtitle, bkgUrl}){
return (
<header className='hero' style={{background: `url("${bkgUrl}")`}}>
<h1>{title}</h1>
<p>{subtitle}</p>
</header>
);
}
V3
export function Hero({title, subtitle, bkgUrl}){
let style = bkgUrl
? {background: `url("${bkgUrl}")`}
: undefined
return (
<header className='hero' style={style}>
{title && <h1>{title}</h1>}
{subtitle && <p>{subtitle}</p>}
</header>
);
}
V4
export function Hero({title, subtitle, bkgUrl, className}){
const style = bkgUrl
? {background: `url("${bkgUrl}")`}
: undefined
const finalClassNames = ['hero', className].join(' ')
return (
<header className={finalClassNames} style={style}>
{title && <h1>{title}</h1>}
{subtitle && <p>{subtitle}</p>}
</header>
);
}
Rinse and Repeat
-
Tile Component
-
Tile Group
-
NavBar
-
List
-
ListGroup
Then I Wired It Up
function LandingPage(){
return(
<div>
{/*...*/}
<Hero
title='Assimilation Point'
subtitle="The Point of Assimilation"
/>
{/*...*/}
</div>
);
}
My "Reusable Components" never got reused
- The Hypothetical "user" never happened
- Almost everything on the landing page were unique to the landing page only
- To quote Chantastic, "My code was so DRY, it chaffed"
Why Didn't I just do this?
function LandingPage(){
return(
<div>
{/*...*/}
<Hero/>
{/*...*/}
</div>
);
}
Or just this?
function LandingPage(){
return(
<div>
{/*...*/}
<header className='hero'>
<h1>Assimilation Point</h1>
<p>The point of assimilation</p>
</header>
{/*...*/}
</div>
);
}
What's the harm?
Minimal API Surface Area
by Sebastian Markbage
No Abstraction > Wrong Abstraction
No abstraction is easier to recover from than the wrong abstraction
Abstractions often lead to more abstractions
Why do we do this?
"It solved our problem in the last app"
(And it still will solve our problem if we just make this one little tweak)
Making Abstractions are Fun
react-clean-form is a package I wrote to abstract away wiring up state and change handlers to form inputs
<Form initialState={{userName: '',password: ''}}>
<input name='userName'/>
<input name='password'/>
</Form>
Under the hood, I recursively found every input and injected the change handler into the jsx
You could do it that way, but....
It provided no value over just using uncontrolled components
<form>
<input name='userName'/>
<input name='password'/>
</form>
Anything more complicated would most likely need a more powerful form abstraction than just simple state management
Abstraction === Procrastination
It's easy to fool ourselves into thinking we are working hard and being productive.
What we are really doing is delaying solving the hard problems we have now, by trying to solve the hypothetical problems of the future
Self Confidence
[We tend to attach our self worth] to something that can be measured. A set of strict lint rules, a naming schema, a file structure, a lack of duplication.
Dan Abramov, overreated.io
It's easy to compensate for our own self-doubt by attributing our worth to how “clever” we can write our code.
How do we stop ourselves?
Only solve the real problems we have now and not hypothetical ones of the future
Only generalize if it is fixing a bug
Make your abstractions worth it
i.e. Can we reuse this abstraction in multiple places in my app? If not, maybe it's not worth solving the problem generally (yet).
The Rule of Three
Be okay with unwinding abstractions
Thank You
- @travisWaithMair
- non-traditional.dev
Stop Writing Reusable React Components
By Justin Travis Waith-Mair
Stop Writing Reusable React Components
- 393