Components are the building blocks of React applications. It’s almost impossible to build a React application and not make use of components. It’s widespread to the point that some third-party packages provide you with components you can use to integrate functionality into your application.
These third-party components tend to be reusable. The difference between them and components you probably have in your application has to do with specificity.
Here’s what I mean. Say you run a company that sells polo shirts. There are two things you can do:
You can produce polos that already have a design on them, or
You can have the buyer choose the design they want.
Some fundamental things will be consistent, like all polos should be short-sleeved. But the user can pick variations of the shirts, such as the color and size. A short-sleeve polo would make a good React component in that case: it’s the same item with different variations.
Now let’s say you’re working on a login form. Like polo shirts, the form has consistent characteristics, but instead of size and color variations, we’d be looking at input fields, a submit button, perhaps even a lost password link. This can be componentized and implemented with variations in the inputs, buttons, links, etc.
Input Element Example
Let’s look at it from the perspective of creating an input field for your form. Here is how a typical text input will look like as a React component:
class Form extends React.Component {
this.state = {
handleChange = (event) => {
this.setSate({ username: })
render() {
return (

To make this input element reusable in other places and projects, we’ll have to extract it into its own component. Let’s call it FormInput.
const FormInput = ({
}) => {
return (

{ error &&

{ error }


FormInput.defaultProps = {
type: text,
FormInput.propTypes = {
name: PropTypes.string.isRequired,
type: PropTypes.string,
placeholder: PropTypes.string.isRequired,
type: PropTypes.oneOf([text, number, password]),
className: PropTypes.string,
value: PropTypes.any,
onChange: PropTypes.func.isRequired
The component accepts certain props, such as the attributes that we need to make the input with valid markup, including the placeholder, value and name. We set up the input element in the render function, setting the attribute values as the props that are passed to the component. We even bind the input to a label to ensure they’re always together. You can see that we’re not making assumptions by predefining anything. The idea is to ensure that the component can be used in as many scenarios as possible.
This makes for a good component because it enforces good markup (something Brad Frost calls dumb React) which goes to show that not every component has to be some highly complex piece of functionality. Then again, if we were talking about something super basic, say a static heading, then reaching for a React component might be overkill. The possible yardstick for making something a reusable component probably ought to be when you need the same functionality in other parts of an application. There’s generally no need for a “reusable” component if that component is only used once.
We can make use of our input component in another component, the LoginPage.
class LoginPage extends React.Component {
state = {
user: {
username: ,
errors: {},
submitted: false
handleChange = event => {
const { user } = this.state;
user[] =;
this.setState({ user });
onSubmit = () => {
const {
user: { username, password }
} = this.state;
let err = {};
if (!username) {
err.username = Enter your username!;
if (password.length < 8) { err.password = Password must be at least 8 characters!; } this.setState({ errors: err }, () => {
if (Object.getOwnPropertyNames(this.state.errors).length === 0) {
this.setState({ submitted: true });
render() {
const {
user: { username, password }
} = this.state;
return (

{submitted ? (

Welcome onboard, {username}!

) : (


Here’s our final login form when all of our components are put together.
See the Pen
Reusable Button Component by Kingsley Silas Chijioke (@kinsomicrote)
on CodePen.
Wanna give this a try yourself? Try working on a reusable