Sharing React Widgets Between Apps

How and why you should share React data-fetching components.

Eden Ella
Bits and Pieces

--

To make things clear— this blog post is not about the react-widgets library.

What do I mean by “widgets”, then?

Widgets are reusable components that handle both logic/data-fetching and presentation.

Before you accuse me of blasphemy for suggesting not to separate UI and logic, let me give you a few examples that might convince you there’s a place for nuance in the all-mighty rule of ‘smart-dumb’ / ‘presentational-container’.

Use Cases for Widget Components

  • When building a component that’s tightly coupled to a specific service by function, purpose, or “concern” (for example, a weather widget).
  • When a UI component and data component, are shown to be used together more often than not.
    A reusable component is a component that is often reused. Don’t let pre-determined design patterns get in the way of you responding to reality.
  • When building multiple apps/static websites that display content from a shared source.
    If the data source is constant for all apps, it could make more sense to have reusable components manage both UI and data-fetching. That could also enable low-code compositions that can be done by marketing and content teams, instead of software engineers.
  • When building (public) static websites that rely on data managed by an organization, internally.
    Say your organization has both an internal Document Management System, and one or more public websites. These websites often include dynamic data that is managed internally in your organization (e.g, contact info, list of branches/offices, up-coming events, etc). You can have your components “pre-connected” to your DMS, and since the data-fetching happens only in build-time, there’s no security risk (for example, using staticQuery in Gatsby websites).

Demo: Sharing and Reusing Widgets with Bit

To demonstrate sharing and reusing React widgets, we’ll create an avatar widget that both fetches and displays an image according to the user’s ID.

The backend part will be handled by a serverless function deployed to Firebase.

The widget and the serverless function will be built in the same repository. Both will be published to Bit’s component hub.

Bit is a tool and a component hub that manages the entire process of sharing components between separate projects.

Example: browsing through shared React components on Bit.dev

Before your components are published to Bit (Github), it tracks them in your project, source-controls them individually, and even builds them isolated from your project.

What all that means is — you don’t need to worry about designing your project in any specific way just so you could share a few components. Bit pretty much handles everything.

We’ll publish both the widget and the serverless function. https://bit.dev/eden/react-widgets
The widget and the serverless function, shared on Bit’s component hub

Setting Up Our Project

We’ll first set up new create-react-app with TypeScript:

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

We’ll then initialize a new Firebase cloud-functions project in our project’s directory (for more info about installing Firebase tools, see here):

$ cd avatar
$ firebase init
// then choose 'cloud functions'...

This will be our project’s structure:

|-- functions <-- created by Firebase
|-- node_modules
|-- index.js
|-- package.json
|--src
|-- components
|-- Avatar
|-- Avatar.jsx
|-- Avatar.module.css
|-- image_placeholder.svg
|-- index.js
|-- node_modules
// etc.

Building the Serverless Function for the Avatar Widget

We’ll first build our dummy serverless function. It should handle our Avatar’s requests (remember, this function is only for a very simple demonstration).

We’ll then deploy it to Firebase:

$ firebase deploy// then, choose between several options

We’ll then create our Avatar widget:

Publishing the Widget and the Serverless Function

We’ll start by installing Bit:

$ npm install bit-bin --global

We’ll then initialize a new Bit workspace in our project’s root directory:

$ bit init

We’ll then start by tracking the Avatar component:

$ bit add src/components/Avatar

And, the serverless function. Here, we’ll also name it ‘avatar-serverless-function’ using the --id flag.

$ bit add functions/index.js --id avatar-serverless-function

To save ourselves from long build configurations, we’ll import one of Bit’s compilers. This one is for React with TypeScript.

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

It’s time to tag both ‘components’ (in the broadest sense of the word), the React widget, and the node serverless function. When we “tag”, Bit builds, tests, and versions components.

bit tag -a

Then, set up a (free) Bit account and create a collection

And… publish! 🎊 🎊 🎊

bit export <username>.<collection-name>

Check out the Avatar widget in my component collection:

When you scroll down, you’ll see the auto-generated docs, created by Bit:

https://bit.dev/eden/react-widgets/avatar

So, how do we reuse the Avatar component?

You’ve got two options.

Choose between NPM/yarn install and Bit import
  1. Use either NPM or Yarn to install it as you normally would, with any other package.
$ npm i @bit/eden.react-widgets.avatar// OR$ yarn add @bit/eden.react-widgets.avatar

2. Use Bit to “clone” it into your repository. This will enable you to develop it in your local environment, and even push it back to its Bit collection, with a bumped version.

$ bit import eden.react-widgets/avatar

Learn More

--

--