Modern React: props for Functional Components
Tags: react, webdev, javascript, tutorial
Published: 2021-01-15 15:33:05

Most websites have recurrent design elements. As a developer, it saves you time and effort to build reusable code snippets for these elements. They are called **components** and React is perfect for creating them.

*Note: For this article, I assume that you are familiar with basic React concepts.*

## Level 1: A reusable component
Imagine your website has cats all over the place.🐱🐱
Let’s build a `Cat` component:

```js
// Cat.js
const Cat = () => <div className="cat">🐱</div>
```
*Note: Inside the `div` we would write our cat JSX.*

Let’s look at the code a little closer. There’s no class, because this is a [functional component](https://reactjs.org/tutorial/tutorial.html#function-components), a modern way to write React. The function is written as an [array function](https://www.robinwieruch.de/react-function-component#react-arrow-function-component), a longer version would be:

```js
// Cat.js
function Cat() {
  return <div className="cat">🐱</div>
}
```

We can use our component anywhere we want:

```js
// App.js
<Cat />
```

If we want to change the cat, we only have to change it once in `Cat.js` and it will be applied everywhere. That’s the idea of components.


## Level 2: An adaptive component
Your `Cat`s are fine. But you dream of a website full of different sorts of cats. A first idea might be to create more cat components:
```js
const Cat = () => ...
const ShorthairCat = () => ...
const BengalCat = () => ...
const PersianCat = () => ...
```
Since the cats only differ in CSS, that’s a lot of JSX repetition. And what’s about your original `Cat` component?  Change every existing `<Cat />` in something more descriptive?

### The solution: React properties

As all our cats share the same JSX, we can use our `Cat` component and modify it a little. It would be convenient to specify which *type* of cat we want when using it:
```js
// App.js
<Cat type="shorthair" />
<Cat type="persian" />
```
`type` is a React property we defined ourselves.
It’s inside the JSX tag as would be an attribute in HTML:
```html
<a href="#">link</a>
```
The `href` attribute in `a`  **specifies** the link’s target. 
The JSX property **specifies** the cat’s type: *I don’t just want any cat, I want the shorthair cat.*

We added a property, but haven’t defined it inside the `Cat` component yet. As for now, React still doesn’t know what’s so special about the persian type cat.

First, we have to add an invitation for properties in our component. We’ll use [JS object restructuring](https://www.robinwieruch.de/react-function-component#react-function-component-props) here to be able to specify exactly what we can use as an argument. 

```js
// Cat.js
const Cat = ({type}) => <div className="cat">🐱</div>
```
We now registered that a cat `type` can be passed to the component. 

If we want to display the shorthair cat, we can pass the property `type`with the value `shorthair`: 

```js
// App.js
<Cat type="shorthair" />
```

We registered `type`as a valid property. If we log the type, we get the desired value.
```js
// Cat.js
const Cat = ({type}) => {
  console.log(type); // shorthair
  return <div className="cat">🐱</div>
}
```

Now, the fun begins. We have to add our shorthair cat’s styling. There are several possibilities to do this – a simple solution is to add a modifier class to be able to define the shorthair cat’s styling in our CSS file. In the end, our HTML result loos like this:
```html
<!-- In the browser -->
<div class="cat cat--shorthair">🐱</div>
```

Every cat has the class `cat`, but if a type is added we want this type to be an additional modifier class.
To be able to do this, we need to prepare the class to change according to the passed type. With [JS template literals](https://dev.to/laurieontech/string-literals-in-javascript-19ck), we can add variables to strings. With the [ternary operator](https://dev.to/cesareferrari/conditionally-assign-a-css-class-to-a-react-component-jk5), we can provide the fallback if no type gets passed.

```js
// Cat.js
const Cat = ({type}) => {
  return (
    <div className={`cat ${type ? `cat--${type}` : ""}`}>
      🐱
    </div>
  );
};
```
*Note: I recommend the React [classnames package](https://www.npmjs.com/package/classnames) which makes dynamic classes much more readable.*

If we want to pass multiple properties, we can do this as follows:

```js
// App.js
<Cat type="shorthair" name="Leo" />
```

```js
// Cat.js
const Cat = ({type, name}) => {
  return (
    <div className={`cat ${type ? `cat--${type}` : ""}`}>
      Cat {name} 🐱
    </div>
  );
};
```

Now it’s your time to try it out. I’ve built a CodeSandbox for you to fork 👇

{% codesandbox react-props-for-functional-components-vtoke %}

- - - -
## Linklist
### React-specific
- [Functional Component](https://reactjs.org/tutorial/tutorial.html#function-components)
- [Array function](https://www.robinwieruch.de/react-function-component#react-arrow-function-component)
- [React logical && operator for conditional rendering](https://reactjs.org/docs/conditional-rendering.html#inline-if-with-logical--operator)
- [Object destructuring for React props](https://www.robinwieruch.de/react-function-component#react-function-component-props) *(second example)*

### Modern JS
- [Template literals](https://dev.to/laurieontech/string-literals-in-javascript-19ck)
- [Ternary operator](https://dev.to/cesareferrari/conditionally-assign-a-css-class-to-a-react-component-jk5)