Build Scalable React Apps by Sharing UIs and Hooks

How to build scalable React apps with independent and shareable UI components and hooks.

Eden Ella
Bits and Pieces

--

Image by Mikki Couch from Pixabay

In this demo, we’ll use Bit to manage our app’s components and hooks as discrete, independent, and shareable building blocks.

Bit offers us:

  • A component-level source-control (alongside our project source-control)
  • Isolated component testings (i.e, isolated from the rest of the project)
  • A platform to inspect a component’s behavior across contexts (i.e, in different compositions)
  • An easy way to document, package and publish individual components

We’ll be using Bit in combination with Bit's cloud service — Bit.dev (which is also free, for most uses). You may also choose to use your own server, instead.

Short demo: Building and sharing independent UIs and hooks

The end result: A collection of a reusable UI component and a reusable hook. Each can be installed/updated independently.

Our “jokes app” will be made of a button component, a hook, and the composition of the two. We’ll use create-react-app to get started.

$ npx create-react-app jokes-app --template typescript

Creating the button (UI) component

The button component file structure:

|-- src
|-- ui
|-- button
|-- button.tsx
|-- button.module.scss
|-- button.spec.js
|-- button.ts

Inside button.tsx :

The above JSDocs comments and TypeScript definitions would be used by Bit to generate the documentation for that component. This documentation would be part of the component page on Bit.dev.

The index.tsc file will export everything, like so:

export * from './button.tsx

Creating the useGetJokes hook

React 16.8’s Hooks have made sharing logic, easier than ever. No need for cumbersome Higher-Order Components or Render Props. Logic is now decoupled from UI and shared between components as elegant Hook functions. Hooks should be thought of as basic (logic) building blocks for our React apps.

The useGetJokes hook will fetch and handle jokes from a jokes API.

|-- src
|-- hooks
|-- useGetJokes
|-- useGetJokes.ts
|-- useGetJokes.spec.js
|-- index.ts

Inside the useGetJokes.tsx file:

Share components to Bit.dev

Install Bit and initialize a Bit workspace:

$ npm i bit-bin -g
$ cd bad-jokes
$ bit init

Start tracking our components (we’ll also use the -n flag to namespace each of them):

$ bit add src/ui/button -n ui
$ bit add src/hooks/use-get-jokes -n hooks

Configure a compiler for our components (remember, they need to be decoupled from our project’s build/bundle setup).
For other compilers, see here.

$ bit import bit.envs/compilers/react-typescript --compiler

Tag our components (commit a component version, test, build, and package):

$ bit tag --all 1.0.0

The tagged components are packaged as individual packages, not as a library! The --all flag is used here as a shorthand to tag both with a single version.

Register to Bit.dev (this is the default remote server for Bit) and create a “collection” for our soon-to-be-published components.

Login to Bit.dev (in the terminal):

$ bit login

Export (publish) components:

$ bit export <username>.<collection-name>// for example:
// bit export eden.jokes-app

The button component and useGetJokes hook are now available to be installed as independent components.

In my collection, I’ve added examples for each. Check it out here:

The end result: A collection of a reusable UI and a Hook. Each can be installed independently.
The useGetJokes hook on Bit.dev (used as part of a demo composition)

Import/Install published components

You can install your published packages (the hook or the button) as regular NPM packages, or you can “import” them using Bit.

“Imported” components are (sort-of) cloned into your project. That means you can change their code, tag them with a new version, and “push” them back to their collection.

For example, let’s import the useGetJokes hook from my collection:

$ cd path/to/new/project
$ bit init
$ bit import eden.jokes-app/hooks/use-get-jokes

It is now available in:

(root)
|-- components
|-- hooks
|-- use-get-jokes

There’s also a symbolic link in the node_modules folder:

|-- node_modules
|-- @bit
|-- eden.jokes-app.use-get-jokes

You can use bit watch to modify the hook (in the components directory) and use its (auto-built) dist in your project.

Conclusion

Hooks and UI components are the basic building blocks of a React application. By sharing them using Bit, we can build maintainable and scalable apps. We can also enjoy faster delivery (as less gets re-written), and maintain a consistent UI/UX.

Unlike standard packages, components shared with Bit are independently source-controlled and packaged. That makes every project part of a “virtual monorepo” (only without the usual overhead).

Related Stories

--

--