Make Refactoring a Breeze in React Native

There comes a time in every project where the project organization becomes non-negotiable. For small projects, simple organizational structures can suffice. However, as a project grows in size and complexity, file organization is critical for maintainability and readability as new developers join the team. In this post, I’ll discuss a technique called barreling that you can use to help organize your React Native projects.

What is a Barrel? 

Put simply, a barrel is a way to aggregate your exports from several discrete modules into a single, neat import line. The barrel itself is an intermediary that handles all the individual module imports, then re-exports each in a concise way. Consider the following structure:
Flat Organization Structure
In addition to confusing views (Home.js) with components (Button.js), the above structure makes for a messy import when adding components. For Home.js, our imports might look something like this: Now, this is all well and good, but if we look closely at just the imports from the react-native library, things look much cleaner: This looks very clean; all of our related items are imported en masse on a single line. Thankfully, we can achieve the same result for our own custom components through barreling!

Do A Barrel Roll

Our first step to barrel our reusable components is to create a sub-folder and add an index.js file. This index.js file will act as our table of contents that exports all of the individual components we want to expose to classes outside the barrel. Here’s what the updated folder structure would look like:
Adding a shared folder to our organization structure
We then can dutifully fill out our manifest of components in index.js, like so: Now, Home.js can consume our exported, barreled components in the following manner: Our imports are much tidier now. Let’s take this a step further and assume in addition to components, we have some functions we’d like to share across various pages in our react-native app. As before, we’ll need to restructure slightly.
Adding a components and functions folder within our shared structure
If we move everything previously created into a new subfolder (called components), we’ll just need to update the path slightly for our component imports in Home.js. Before that, however, we’ll need to create a new index file for out functions, like so: Now, we can refactor Home.js to point to the proper index files, as well as use our functions: Home.js is now looking very tidy, and we’ve also set our project up nicely for reuse. That said, there is a little more work we can do to make our project files even cleaner still. Let’s assume our ./shared/components files contains some very complex components – long, lengthy styles sheets paired with detailed markup for render. Consider the following folder structure:
Each component now has its own index file
Here, each component has its own index file, which would look something like this: And our updated index.js file in ./shared/components would look like so: No further modification is required for Home.js at this point – since we’ve effectively put our barrels in a bigger barrel, our imports and usage in Home.js doesn’t have to change.

One More Thing…

Taking this concept even further we can create a super barrel to roll up everything in our shared folder to make imports a cinch. Contemplate the following folder structure:
Individual structure per component
Where our top-most index.js looks like so: Now, we can condense all of our various shared sub-folder barrels into a single import. Personally, I have mixed feelings about this last step; in my projects, I prefer to import my barrels by category, rather than import them all wholesale, but this can be useful if you find yourself using most (or all) of your barreled components across many files. Either way, it’s a nice option to keep in your back pocket should the need arise.  And that’s a wrap, folks! I hope you’ll consider leveraging barreling in your react native projects to keep your projects tidy and neat! 

Leave a Reply

Your email address will not be published. Required fields are marked *