Skip to content

Instantly share code, notes, and snippets.

@bennadel
Created June 24, 2017 12:27
Using BEM Class Names To Guide Module Structure In React 15.6.1
// Import the core React modules.
import React = require( "react" );
// Import the application modules.
import { Contact } from "./interfaces";
export interface OnDelete {
( contact: Contact ) : void;
}
// ----------------------------------------------------------------------------------- //
// ----------------------------------------------------------------------------------- //
interface ContactListProps {
contacts: Contact[];
onDelete: OnDelete;
}
// NOTE: We are using a Function instead of a Class here because this is a stateless
// component that doesn't need to expose any additional methods. As such, we can provide
// what is essential just the render() method. The props are still type-checked against
// the Props {} interface.
export function ContactListComponent( props: ContactListProps ) : JSX.Element {
var contactListItemNodes = props.contacts.map(
( contact: Contact ) : JSX.Element => {
return(
<ContactListItemComponent
key={ contact.id }
contact={ contact }
onDelete={ props.onDelete }>
</ContactListItemComponent>
);
}
);
return(
<div className="contact-list">
{ contactListItemNodes }
</div>
);
}
// ----------------------------------------------------------------------------------- //
// ----------------------------------------------------------------------------------- //
interface ContactListItemProps {
contact: Contact;
onDelete: OnDelete;
}
interface ContactListItemState {}
class ContactListItemComponent extends React.Component<ContactListItemProps, ContactListItemState> {
// I render the component.
public render() : JSX.Element {
return(
<div title={ `Contact ID ${ this.props.contact.id }` } className="contact-list__item">
<div className="contact-list__name">
{ this.props.contact.name }
</div>
<div className="contact-list__actions">
<a onClick={ this.handleClick } className="contact-list__action">Delete</a>
</div>
</div>
);
}
// ---
// PRIVATE METHODS.
// ---
// I handle the delete click.
// --
// CAUTION: Using an instance-property to define the function so that we don't lose
// the "this" context when the method reference is passed into the React element.
private handleClick = ( event: React.MouseEvent<HTMLAnchorElement> ) : void => {
this.props.onDelete( this.props.contact );
}
}
export function ContactListComponent( props: Props ) : JSX.Element {
var contactListItemNodes = props.contacts.map(
( contact: Contact ) : JSX.Element => {
return(
<ContactListItemComponent
key={ contact.id }
contact={ contact }
onDelete={ props.onDelete }>
</ContactListItemComponent>
);
}
);
return(
<div className="contact-list">
{ contactListItemNodes }
</div>
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment