How Did I build My First React Package
Tags: react, javascript, frontend, recurrence
Published: 2021-06-13 21:17:17

## Motivation

There are a lot of use cases that require the concept of repetition or recurring. A basic example for that is recurring events.

A highly customizable component that you can plug into your project to have the recurring logic in no time is quite needed for such cases.

## Development Process

At first, I didn't have the full picture of how my component will look like, what will be the end result, what are the internal components, or how can I make it as customizable as possible. Since recurring logic is mostly used with calendar events, The first step I did is checking existing behavior in different well-known calendars such as Google Calendar and Outlook Calendar. After that, I was able to imagine the main parts of my component, which are:

- **Start Date**
- **Frequency**
- **Ending Condition**
- **if it's all day or with Start and End Time.**

### "Make it work, Make it better" Ideology

#### Make it work

When I started the development process, I had one big react component that contains all the logic of the main parts I mentioned. I built the general structure from UI perspective with some stylings here and there until I got the following:

![React Recurrence general structure.](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7caz239lwfq752x6fee0.png)

The next step was defining my recurrence object and the type of each internal field. And here it came the blessings of typescript. At first, I had some difficulties dealing with it, but then, I realized how helpful it is.

After that, I defined the click/change events for each input I had in the component in order to correctly fill the recurrence object fields.

So I got a working component! (but really, not a one I can be proud of yet, nor a customizable one. 😏)

#### Make it better

The most challenging part during the component development is the continuous thoughts of how can I make it better. Making a component better is by making it cleaner as code along with a cleaner logical separation into sub-components.
More importantly, make it as customizable as possible by thinking of other use cases that the consumers or the users of your component will face  while using it. Of course, adding some unit tests is another strength to make sure nothing breaks when any refactor is done in any part of the component.

- **Component Separation**

    The following GIF sums up the process of separating the large component I started with, into  sub components. Each sub-component represents the main parts I mentioned earlier since each part is a separated logic and can live inside its own component.

![Internal Components](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ws8uphi36p4df0hhzbhy.gif)

- **[React Context](https://reactjs.org/docs/context.html)**

    After doing the components separation, I first used the tradition way in react for passing the data between the children which is using props. But then, I realized that the result was a tree of components and some props needed to be passed into deeper children. Here, React Context came into play.


    The first advantage I had from using Context is that the recurrence object is shared between the sub-components and no need to pass each field as a prop. 


    Another advantage was giving the consumer the flexibility of structuring the sub-components according to their needs. As a result of this, the component can be used in either the default structure:

    ```jsx
    <Recurrence
      recurrence={recurrence}
      onChange={handleRecurrenceChange}
    />
    ```

    Or in a custom one:

    ```jsx
    <Recurrence
      recurrence={recurrence}
      onChange={handleRecurrenceChange}
    >
        <Grid
          container
          direction='column'
          justify='center'
          alignItems='center'
          spacing={3}
        >
          <Grid item xs={12}>
            <Recurrence.StartDateSelector/>
          </Grid>
          <Recurrence.FrequencySelector/>
          <Grid item sm={12}>
            <Recurrence.EndingConditionSelector/>
          </Grid>
          <Grid item sm={12}>
            <Recurrence.TimeSelector/>
          </Grid>
        </Grid>
    </Recurrence>
    ```

- **Styling**

    [Material UI styling](https://material-ui.com/styles/basics/) solution was the choice to build a dynamic UI for the component.

- **[Storybook](https://storybook.js.org/)**

    Storybook helped a lot in representing the different states of the recurrence component along with the subcomponents in an isolated way. 

- **Unit Tests Using [Jest](https://jestjs.io/docs/tutorial-react)**

    Unit tests helped me a lot when I reached the refactor part to make my component better. I wanted to make sure that no change will affect the logic of the component. 

## Useful Tools

The following tools made my life easier while developing the component and publishing it.

- [create-react-library](https://github.com/transitive-bullshit/create-react-library)

    This package helps a lot when creating a new react library since it saves you from all the boilerplate code and the setup needed. 

- [np](https://github.com/sindresorhus/np)
This package makes your life easier when dealing with publishing and releasing your component to NPM.

## Demo

A live demo for the component can be found [here](https://ziadadeela.github.io/react-recurrence/).


## Github Repository

Feel free to review the component to give any technical feedback or drop any suggestions on how to make it even more customizable. You can find it [here](https://github.com/ziadadeela/react-recurrence).

## Get Help

A great source for getting help around the library or the tool you're using is its community. Most of the times you will find people to help you when you're stuck or to take their opinion in some cases to make sure you're following the best practice of the tool.

 **[Reactiflux](https://www.reactiflux.com/)** helped a lot in React, Context, and Jest for some of the cases I faced in react-recurrence. Same thing regarding [Storybook](https://storybook.js.org/community) community.