How to Fix Your First Bug in an Existing React/Redux Project
When you first join a new dev team or contribute to a new open source project, getting started can be a little daunting. Often times, familiarizing yourself with an existing code base can feel like being thrown right into the deep end of a pool. Your team might give you a brief tour of the project, and you might have some background knowledge to put to use too, but you still won't really know your way around until you actually dig in for yourself.
In this post I'll candidly describe my experience fixing my first bug in an existing project that was brand new to me. I hope my experience and the techniques I used can be useful to other developers who are likely to find themselves in the same position at some point in their careers.
My Task
The project I was walking into for the first time was the code base of ReQLPro, a native desktop app built with React and Electron. The app is used to help manage RethinkDB databases, many of which contain tables that have multiple pages, and the bug that I needed to fix was basically a pagination issue. The problem was that if a user navigated to the last page of a table with 10 pages, then switched to a table with only 1 page, it would cause the app to end up in a weird state. I needed to make sure the page of the last table didn't influence the state of the next table.
Getting Started
I set out knowing that navigating to a new page in the current table would somehow cause errors when changing tables. Knowing little else about how the database connections were handled, I started out to simply see how ReQLPro was storing the current page number, then figure out what it did with that information when the table was changed. I figured that the first place to look was the display, so I started by looking for strings where the page number was presented to the user and then looked for those strings in the code.
In the ReQLPro app, I dug around the tables that were available to me until I found one with multiple pages. I then used the bottom panel to navigate to another page. I saw the current page number displayed as below:
I figured that the numbers would be variables and couldn’t be directly searched for in the code without knowing their names, so I started by searching for what I figured would be a static string, i.e. “(Page”
.
This proved to be a success, leading me to the currentPage
variable in ExplorerPagination.js
However, currentPage
seemed to be taking its value from a variable (table
) that wasn’t defined anywhere in that file. I figured that PageDetails
, its parent component, was being called from elsewhere and being supplied with the table
variable from there. I searched the project for PageDetails
to get more information. This just led me back to the same file, where I saw that PageDetails
was being called from the ExplorerPagination
container which was itself exported and being used elsewhere. So I then searched the project for ExplorerPagination
.
This led me to ExplorerFooter.js
, which I saw was defining table
from the state:
I continued the search for selectedTable
. This led to a ton of search results, but after some digging I came to setSelectedTable
in a file called core.js
.
It looked to me like calling this function would set the query page to 1 (line 94). I figured that this function was being called when a new table was being selected, but that somehow the query wasn’t getting its page changed.
I searched for setSelectedTable
and found it in main.reducer.js
.
Now I'm on to something...
Based on my limited React/Redux experience I figured that SET_SELECTED_TABLE
was being used to set the selected table, so I continued the search with that.
I found it DbTable.js
.
I figured that once the table was clicked on, then SET_SELECTED TABLE
would be called. What happened next? It looked like the default query (i.e. setting the query page to 1) would be used only if selectedTable
was undefined at the time of the click (in the ‘else’ condition on line 44). If selectedTable
was defined then selectedTable.query
would be used.
I then figured that the problem was occurring because navigating to another table would use the query from the current table. If the current table query was set to page 2, then the next query would be page 2 as well. The user would have to navigate back to page 1 on the present table before navigating to a smaller table to guarantee that the next table query would be for page 1 itself.
Fixing the issue
I fixed the issue by adding the following to the condition (line 42):
This ensured that the current table query would be used only if the user clicked the same table on the side panel. It did so by checking that the next table name was identical to the current table name - if it is not identical then the default page of 1 would be used for the selected table query. This, as near as I can tell, resolves the reported issue.
In summary...
I didn’t encounter any glaring technical faults as I went - my primary challenge was unfamiliarity with the codebase, and I hope that my account here helps elucidate what a new user would encounter as they begin work on this project or any new project.