Skip to content

Instantly share code, notes, and snippets.

@dcolucci
Last active December 6, 2016 01:12
Show Gist options
  • Save dcolucci/8108f148cb2727f907b61da29a21631b to your computer and use it in GitHub Desktop.
Save dcolucci/8108f148cb2727f907b61da29a21631b to your computer and use it in GitHub Desktop.

presentation flow

  1. Intro, why this topic, disclaimer
  2. note about TDD versus traditional dev
  3. Show an example of a complex view component
  4. Points why it is difficult to work with
  5. Walk through breaking it up into smaller components
  6. If you need helper functions - make them pure!
  7. React component philosophy
  8. stateless when possible
  9. as little business logic in the view layer as possible
  10. try not to couple views to store
  11. Transition to testing them
  12. Example of insufficient test
  13. Test choices & philosophies
  14. expect vs. assert
  15. sinon + chai + mocha + enzyme
  16. advantages of enzyme over ReactTestUtils
  17. How to write tests? 2 steps
  18. Look at your component and think about every element of logic involved
  19. Think of edge cases
  20. Questions to ponder

separation of view & app state

say the store sets some state key like so

this.currentState = {
 someArray = data.someArray || []
};

And the view does something like

render() {

 // is this fallback necessary??
 const someArray = this.props.someArray || [];
 
 return (
   <div>
     {someArray.map(item => <div>{item.name}</div>)}
   </div>
 );
}

Is the fallback necessary?

pure helper functions

stateless functional components

https://hashnode.com/post/component-rendering-performance-in-react-ciqti6xlz06n49l53t2c2g3ri

overloaded components and multi-layered view API

// some consumer view render
<MyComponent isSpecial={true} />

// <MyComponent> render
{this.props.isSpecial && <div>I am special</div>}

consider instead:

// some consumer view render
<MySpecialComponent />

// MySpecialComponent render
<MyComponent isSpecial={true} />

// another consumer view render
<MyUnspecialComponent />

// MyUnspecialComponent render
<MyComponent />



<MyComponent isSpecial={true} />

// internally wrap an instance of MyComponent
<MySpecialComponent />
<MyUnspecialComponent />


render() {
 return (
  <div className="my-component">
   {this.props.title && <h1 className="my-component-title">
    {this.props.title}
    </h1>
   }
   <div className="my-component-byline">
    <div className="my-component-byline-author">
     {`By ${this.props.author}`}
     </div>
    <div className="my-component-byline-date">
     {this._formatDate(this.props.publishDate)}
    </div>
   </div>
   <article className="my-component-content-body">
    {this._getContent(this.props.content)}
   </article>
  </div>
 );
}

render() {
 return (
  <div className="my-component">
   <MyComponentTitle title={this.props.title} />
   <MyComponentByline
    author={this.props.author}
    publishDate={this.props.publishDate} />
   <MyComponentContent content={this.props.content} />
  </div>
 );
}
_isSuperSpecial() {
 if (!this.props.isSpecial || _.isEmpty(this.props.foo) {
  return false;
 }
 
 return this.props.foo.bar
     && this.props.foo.bar > MAGIC_NUMBER;
}


_isSuperSpecial(isSpecial, foo, magicNumber) {
 if (!isSpecial || _.isEmpty(foo)) {
  return false;
 }
 
 return foo.bar && foo.bar > magicNumber;
}

example: AD nav / subnav: https://github.com/CondeNast/autopilot-ad/blob/7c6b95663ca9667b69e11b4a742e88d06ad6ed56/lib/app/views/components/Navigation.jsx#L63

testing ideas

  • export each individual component as well as the default export
  • set up a command to test an individual file without linting, coverage rpt
  • useful links
  • most useful enzyme methods / gotchas
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment