Intro

This post is about some of the challenges I encountered when using Wix’s React Native Calendars library to implement a date picker for an app I was building for a client.

How and why I chose to use Wix’s library over others is a little out scope of this post but I’ll say that after having good experiences with some of Wix’s other React Native libraries (React Native (Push) Notifications, React Native Navigation) I went with their calendar implementation because it appeared flexible, had Typescript typings and a good support process in the issue queue.

For anybody who lands here doing some discovery on the other options here are what appear to be the main ones:

The challenges I faced using Wix’s React Native Calendars fall into three areas that I will discuss below:

What is React Native?

React Native is a library developed by Facebook to facilitate the use of React in iOS and Android mobile app development. It doesn’t completely preclude the need for platform (iOS/Android) or languages (Java/Swift/Objective C) specific knowledge but it does provides a React friendly environment to develop mobile applications predominantly in Javascript.

Typescript type definitions

Typescript typings are available from the community via the eminent DefinitelyTyped project. To use them in your project run one of the following:

A note on community provided type definitions

This is great news as whilst types for most things can be found that is not always the case. One of the biggest downsides to community provided typings is that they can be out of date as the projects they support continue to evolve or sometimes they are not completely accurate. The consumers of community typings have immense gratitude to the community providing them but there is always work to be done. It is important to highlight here that you can help, if you found typing issues check out how to contribute.

The problem

The problem with type definitions lies here. I have extracted this into a gist for ease of reference here.

React Native Calendars has a lot of features such as marking a multi-day period and marking multiple different events on a particular day, the takeaway is that multiple forms of marking are supported by the DayComponent at the same time. Given that it makes sense that the type definitions specifies an array of data.

However, the if you choose to use the basic day component, which is the default, the marking/selected behaviour is unexpected. Given an array of marking data it overrides this with an object with a single marking property that is effectively meaningless and results in marking/selected not being applied appropriately. It seems to expect a single instance of a Marking type as defined in the community types, not an array.

A solution

To get around this you when using the basic day component you need to pass an object of marking data instead of an array as the typing inconsistencies are internal to the library which is not natively typed.

A different solution if you are using a custom Day component

My position was that I had built out most of my implementation using the library but at the very end I realised I would need to use a custom Day component to achieve the styling our design specs required. That’s no problem as the library supports this out of the box. I only really wanted to reimplement the basic Day component with some layout tweaks I couldn’t achieve using the theme overrides. It is a simple component, the library’s other Day components have added complexity to handle multiple marking types.

By reimplement, I of course mean copy & paste and tweak to my needs. This where I encountered the type definition problem above as I was directly using the DayComponentProps against my custom component.

This meant the Typescript build process and my linter was going to be upset because the typings do not support the behaviour of the basic Day component. This is not allowed:

Typescript has awesome Utility Types that can help here, and help whenever you want to manipulate type definitions. In the gist below you can see that I used Omit type to selectively redefine only the marking property of the libraries native type. That’s it, problem solved. I could have also handled receiving an array of marking but there are additional complexities with the community types in that the Marking type is a Union of conflicting types. To handle an array would require more typeguarding than I was comfortable with.

Where does the problem lie?

I haven’t made any PRs about these issues because I’m not sure if the problem lies in the type definitions or in the library itself or perhaps a bit of both.

Custom Day component

I have come to React fairly late in the game and was generally put off by Class components. I found their readability and complexity too high or the proliferation of wrapper components trying to avoid that too much of a rabbit hole.

Now Functional components I can get on board with, and hooks I am really enjoying! Having said that, there is a lot to learn with functional components, I aim to only ever use them but for some of the Class component behaviours it is not always obvious how to replicate them.

When using a custom Day component with React Native Calendars you are responsible for handling the shouldComponentUpdate logic as the library almost exclusively relies on being able to intervene at this lifecycle point to remain performant. Functional components are just function so no lifecycle methods unfortunately…

Functional components componentShouldUpdate

After a bit of research I found React.memo, which isn’t exactly the same as the shouldComponentUpdate lifecycle method but for most use cases it is going to be good enough. It is a HOC that by default compares props, but can also takes an isEqual func arg to allow you to implement your own comparison logic. As you can see below this can be leveraged to improve the rendering performance of the my custom Day component, for an idea of how much the UI transition between selected and non selected was taking almost a second and now it is immediate.

The end

There is no sample repo/project to go with this post, but the gists above provide the context and some implementations on how the challenges I faced can be resolved.

I would recommend Wix’s React Native libraries, they are some of the most reliable out there. But I must admit they are starting to feel a little dated and I’m not sure how much appetite Wix have to keep them up to date with the React ecosystem.

Get in contact

If you have comments, questions or better ways to do anything that I have discussed in this post then please get in contact.