Skip to content

Instantly share code, notes, and snippets.

@austinpray
Last active September 19, 2018 19:43
Show Gist options
  • Save austinpray/1d697534d1a2c28dfd384a55c74b2375 to your computer and use it in GitHub Desktop.
Save austinpray/1d697534d1a2c28dfd384a55c74b2375 to your computer and use it in GitHub Desktop.
PostListing Refactor. I'm using .jsx filenames so I can get proper filenames in the gist use .js or typescript in your project
import React from 'react'
const PostListing = ({post}) => (
<article>
<h3>{post.frontmatter.title}</h3>
<span>{post.frontmatter.date}</span>
<p>{post.excerpt}</p>
</article>
)
export default PostListing
import PostListing from './bad.jsx'
export default class Stateful extends Component {
// state
render () {
const {posts} = this.props;
return <div>
{posts.map(p => <PostListing post={p} />)}
</div>
}
}
// a year later in some file created by someone else
// this is totally valid
import Post from './bad.jsx'
export default class SomeOtherStateful extends Component {
// state
render () {
const {posts} = this.props;
return <div>
<h1>Some other component</h1>
<Post post={p} />
<p>so i'm scanning this file a year later or code reviewing and im like "wait is PostListingComponent the same as 'PostListing'"?</p>
<p>proceed to waste time looking at the imports and stuff</p>
<p>Also if I want to do a quick grep outside my IDE for 'PostListing' this file will get missed</p>
</div>
}
}
import React, {Component, PureComponent} from 'react'
import pt from 'prop-types'
import cx from 'classnames'
import styles from './goodstyles.scss'
/*
by using PureComponent and keeping the props object shallow and using immutable
types (string, int, bool) this will not rerender if the props don't change
*/
export class PostListing extends Component {
render() {
const {children, url, className, ...props} = this.props;
return <article className={cx(styles.panel, className)} {...props}>
{children}
{url && <div className={styles.footer}>
<a href={url}>Go to post</a>
</div>}
</article>
}
}
PostListing.propTypes = {
url: pt.string
}
export class PostListingFrontmatter extends PureComponent {
render() {
const {title, date, ...props} = this.props
return <div {...props}>
<h3>{title}</h3>
<span>{date}</span>
</div>
}
}
PostListingFrontmatter.propTypes = {
title: pt.string.isRequired,
date: pt.string.isRequired
}
import React, {Component} from 'react'
/*
I'm using .jsx filenames so I can get proper highlighting in the gist. Use .js
or typescript in your project
Also: note how the name is forever forced to be PostListing. When you do a
project wide search or refactor it will always be PostListing
*/
import {PostListing, PostListingFrontmatter} from './good.jsx'
import styles from './styles.scss'
export class Stateful extends Component {
// state
render () {
const {posts, featuredPost} = this.props;
return <div>
<p>This article page sure has some reusable react components!!!</p>
<h1>Featured Articled</h1>
<PostListing className={styles.featured} url={featuredPost.url}}>
<figure>
<img src={featuredPost.someImageSrc} />
<p>{featuredPost.excerpt}</p>
<p>{featuredPost.date}</p>
</figure>
</PostListing>
<h1>The rest of the posts</h1>
{posts.map({frontmatter, ...p} => (
<PostListing {...p}>
<PostListingFrontMatter {...frontmatter} />
<p>{p.excerpt}</p>
</PostListing>
)}
</div>
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment