The goal of this step is to practice creating and composing React components. Components let you split the UI into independent, reusable pieces, and think about each piece in isolation. Components can refer to other components in their output. This lets us use the same component abstraction for any level of detail. A button, a form, a dialog, a screen, etc. In React apps, all of these are commonly expressed as components.
Conceptually, components are like JavaScript functions. They accept arbitrary inputs (called "props") and return React elements describing what should appear on the screen.
Once again, if you run into trouble with the tasks or exercises, you can take a peek at the final source code.
The App
component has quite a bit of markup in it, even though it doesn't do much yet. Break up the large App
component into smaller EmailList
, EmailView
& EmailForm
components and reference them back in the App
component:
class EmailList extends PureComponent {
render() {
return (
<ul class="email-list">
<li>
<div className="email-list-item">
<span>[email protected]</span>
<span>Mauris lacinia sapien quis libero.</span>
</div>
</li>
<li>
<div className="email-list-item">
<span>[email protected]</span>
<span>Mauris ullamcorper purus sit amet nulla.</span>
</div>
</li>
<li>
<div className="email-list-item">
<span>[email protected]</span>
<span>Suspendisse potenti.</span>
</div>
</li>
</ul>
);
}
}
class EmailView extends PureComponent {
render() {
return (
<div className="email-view">
<h2>View selected email</h2>
</div>
);
}
}
class EmailForm extends PureComponent {
render() {
return (
<div className="email-form">
<h2>Add a new email</h2>
</div>
);
}
}
export default class App extends PureComponent {
render() {
return (
<main className="app">
<EmailList />
<EmailView />
<EmailForm />
</main>
);
}
}
The top-level App
component is now composed of the EmailList
, EmailView
& EmailForm
components. It's also much easier to see what makes up the App
component now that the three smaller components have been extracted out.
The EmailList
component is still logically made up of several list item components, which can be extracted into a EmailListItem
component with configurable props:
class EmailListItem extends PureComponent {
render() {
let {from, subject} = this.props;
return (
<div className="email-list-item">
<span>{from}</span>
<span>{subject}</span>
</div>
);
}
}
class EmailList extends PureComponent {
render() {
return (
<ul class="email-list">
<li>
<EmailListItem
from="[email protected]"
subject="Mauris lacinia sapien quis libero."
/>
</li>
<li>
<EmailListItem
from="[email protected]"
subject="Mauris ullamcorper purus sit amet nulla."
/>
</li>
<li>
<EmailListItem
from="[email protected]"
subject="Suspendisse potenti."
/>
</li>
</ul>
);
}
}
The attributes passed to components are called "props." Those props are then available under this.props
within the component class definition.
Components can also be declared using functions instead of classes:
const EmailListItem = ({from, subject}) => (
<div className="email-list-item">
<span>{from}</span>
<span>{subject}</span>
</div>
);
But we'll continue to use the class
syntax so that we can define propTypes
for EmailListItem
:
// back up top add new import of `prop-types` lib
import PropTypes from 'prop-types';
class EmailListItem extends PureComponent {
// declare types of expected props
// i.e. the component's interface
static propTypes = {
from: PropTypes.string.isRequired,
subject: PropTypes.string.isRequired
}
render() {
let {from, subject} = this.props;
return (
<div className="email-list-item">
<span>{from}</span>
<span>{subject}</span>
</div>
);
}
}
Move each component into its own file under a new src/components/
folder, import
ing and export
ing as necessary. For example in EmailList
:
import React, {PureComponent} from 'react';
import EmailListItem from './EmailListItem';
export default class EmailList extends PureComponent {
render() {
return (
<ul className="email-list">
<li>
<EmailListItem
from="[email protected]"
subject="Mauris lacinia sapien quis libero."
/>
</li>
<li>
<EmailListItem
from="[email protected]"
subject="Mauris ullamcorper purus sit amet nulla."
/>
</li>
<li>
<EmailListItem
from="[email protected]"
subject="Suspendisse potenti."
/>
</li>
</ul>
);
}
}
Afterwards, use the React Developer Tools to inspect the component hierarchy, including the props being passed to the EmailListItem
components.
Go to Step 3 - Lists.