Introduction
React Pipelines is a React package that follows a declarative and decoupled approach to making React components more maintainable. In some ways, it is more like a micro framework. The package helps the developer achieve this by being a utility package that helps to create and decouple complex flows of business logic.
In short - this package is a collection of React components and hooks that enables decoupling business logic into smaller resuable tasks.
This is accomplished by wrapping each self-contained section of logic
into multiple smaller React components - we call this a pipe
(since it will be a part of a larger pipeline).
The timing of the executing of the pipe logic is then determined by where in our pipeline
the pipe is rendered. A pipeline
is a React component that wraps and tracks the order of
any amount of pipes. Whenever a pipeline is triggered to execute,
all of its pipes are executed in sequence or parallel.
For some examples inspired by real-life components, take a look at this page.
#
What does the package contain?The core @morningtrain/react-pipelines
package only contains a very limited set of
pipes and triggers. If we were to add additional helper components, it would only further increase the package dependencies.
Instead, we aim to keep the number of components provided in the package to a bare minimum and let other projects and packages implement the more use-case-specific functionality.
The package is documented through the following sections:
#
Getting startedThis is the current section. Besides a short introduction, it also contains installation details, best practices, and some common real-life examples of how the package can be used.
#
PipelinesThis section highlights the base pipeline components: Pipeline, AsyncPipeline, NestedPipeline, and NestedAsyncPipeline. ConditionalNestedPipeline, and ConditionalNestedAsyncPipeline. ErrorPipeline, and ErrorAsyncPipeline.
#
PipesThe section about pipes contains details about the following base pipes provided by the package: CallbackOnPipe.
#
TriggersThe section about triggers contains details about the following base triggers provided by the package: TriggerPipelineOnClick and TriggerPipelineOnCallback.
#
ConditionalsThis section contains information about the two conditional components provided by the package: WhenIsPiping and WhenIsNotPiping.
They will conditionally render their children (or not) based on whether or not the parent pipeline is in an executing state or not.
#
HooksThe section about hooks contains information about the following provided React custom hooks: useWillPipe, useIsPiping, and usePipeline
#
CookbookThe cookbook section contains extra information and examples of how to implement some common use-cases.
#
Why React Pipelines?This section will introduce the why and how about the React Pipelines package.
It will provide a look into the reasoning why the package is needed, and a brief overview of how it is implemented.
React is hard to learn but even harder to master. This is especially the case when it comes to making React code that has a clean structure and is easy to maintain.
Let us try to illustrate the case by showing some code samples for two different approaches.
#
How it could be done using spaghettiThis is a very crude example to illustrate a point. Each section of the promise could still be extracted into helper functions to make them more reusable.
It does however increase the risk of introducing bugs when having to implement the Promise chain manually in every component.
#
The declarative approachA higher degree of decoupling between React components is encouraged by aiming at keeping project-level React components free from complex non-JSX code.
Instead of implementing the logic inside the component like in the spaghetti example above, the following example is how it can be done using pure JSX.
The logic executed in each step of the promise will in this case have to be implemented as custom pipes.
#
How does it work?At its core - it is all about JavaScript Promises.
A pipe
is a Promise-resolvable function (it should return a promise but might also return the payload directly).
The AsyncPipeline implements Promise.all
to resolve all pipes asynchronously
while the generic Pipeline component chains Promise.then
calls synchronously.