4 Tips for Building Reusable and Shareable React Components
Tags: react, reactnative, typescript, javascript
Published: 2020-03-25 15:55:31

### 1. Type-check components with TypeScript

Type-checking is essential for positive developer experience and optimized code collaboration - it what makes your reusable code easy to use and maintain.

__Why TypeScript (or, why not prop-types)?__ 
TS and prop-types are not alone in this game but they are certainly the most popular. The two are different in the way they operate and even in the way they're used (TS validates types at compile-time, whereas prop-types performs at runtime) - nevertheless, it is a fact of reality that the two are rarely used on the same project. That isn't surprising as the two do overlap quite considerably in the way they're used - and, with all due respect to dev ex, there's still a product to deliver.

If you ever used TypeScript you know it serves a much greater role than prop-types. It offers intelligent code suggestions in supported IDEs, it shortens useful and otherwise cumbersome JS code (e.g, Enums) and in general, once you get the hang of it, it shows its strengths by saving time in fixing bugs or simply figuring out your teammates' code. 

Moreover, TS is trending and may even become the new standard for web development. That certainly makes it something worth investing your time and effort.


When using tools to collaborate on components across repositories (e.g, shared [Bit](https://bit.dev) components or even [Git Submodules](https://git-scm.com/book/en/v2/Git-Tools-Submodules), TS really shows its strengths by providing component consumers with a clear API, and component collaborators with a more explicit and intelligible code.

<figure>
  <a href="https://bit.dev"><img alt="Example: Browsing through shared components @ Bit.dev" src="https://miro.medium.com/max/800/1*Nj2EzGOskF51B5AKuR-szw.gif" /></a>
  <figcaption>Example: Browsing through shared components @ Bit.dev</figcaption>
</figure>

### 2. Defining Props & Event is Not Enough

Components should be typed as well; otherwise, implicit assumptions are not communicated to TS and unwanted errors start to appear.

For example, a functional component should be types like so:

```const AComponent: React.FC<IProps> = (props : IProps) => {...}```

Otherwise, TS will not expect the ‘children’ prop or a return type that must be assignable to JSX.Element

For example (an un-typed component):

{% gist https://gist.github.com/giteden/c634b1701371fdda004dedbad6735a69 %}

Used like so:

```
function App() {
return (
<div className="App">
        <Button color='day'>a lable!</ButtonA>
    </div>
  );
}
```

Will produce an error, informing you that 'children' were not expected:

```
Type '{ children: string; color: "day"; }' is not assignable to type 'IntrinsicAttributes & IButtonProps'.

Property 'children' does not exist on type 'IntrinsicAttributes & IButtonProps'.
``` 
 

### 3. Write React with TS to Auto Generate Docs 

Auto doc-generation is another great thing you can expect to enjoy when using TS (but in that case, also with prop-types). To make that happen, make sure you define your components' type/interface both as a generic of ``React.FC<T>`` and (directly) as the function's argument type. Otherwise, your props would simply not be included in the generated docs (at least not when using [react-docgen](https://github.com/reactjs/react-docgen) / [Bit.dev](https://bit.dev))

For example:
{% gist https://gist.github.com/giteden/10be4e339c0b719299b25cb05bb92d29 %}

Moreover, make sure to complement your TS with descriptions written using the JSDocs syntax.

For Example, this:

{% gist https://gist.github.com/giteden/f5132b0fe2fb6f02971184bbe4fde55d %}

Will generate this:

<figure>
  <a href="https://bit.dev/eden/react-ts-demo/removable-list-item"><img alt="Generated Doc on a component page." src="https://miro.medium.com/max/807/0*i-Ju6f8Iua81rg-f.png" /></a>
  <a href="https://bit.dev/eden/react-ts-demo/removable-list-item"><figcaption>Auto-generated documentation on component page.</figcaption></a>
</figure>


[Check out React-docgen playground](http://reactcommunity.org/react-docgen/)

### 4. Extend Native-HTML-like Components with React's Interfaces

<img src="https://miro.medium.com/max/1654/1*d_cNV9_7GO3XsdcGf4SMeQ.png" />

Before we start, two files you should definitely get familiar with are: React's index.d.ts and the global.d.ts files.

They're both installed when you add React to your project (if you used npm, you'll find them inside the npm_modules/@types/react folder.

These files contain type and interface definitions used and offered by React, so if you need to extend a native-HTML-like component - that is where you'd find it.

For example, let's say I have a Button component that behaves, more or less, like a native HTML button element (e.g., it can have a label, it has a 'disable' prop, etc.). I can and should enjoy all the implicit definitions that come with such a component, using React's types.

{% gist https://gist.github.com/giteden/a2a16c90f70d54a63d09113506dfd5b8 %}

<img src="https://storage.googleapis.com/static.bit.dev/lp-assets/devto/Screen%20Shot%202020-03-23%20at%2023.12.03.png" />

### Conclusion
This post is far from being a comprehensive guide to building reusable components but I do hope I've managed to clear up a few important issues. React with TypeScript, together with the right tools for component collaboration, offer a great way to increase collaboration and build a more maintainable and scalable code.

### Related posts

{% medium https://medium.com/bitsrc/building-a-react-design-system-for-adoption-and-scale-1d34538619d1 %}