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