React.js has been successfully added to out Asp.Net MVC web app in part 1.
I created a React driven user listing and maintenance page on part 2.
In this post, I will create a Custom Hook to remove the need to use the same piece of code in each React web page.
Copy Paste Programming, DRY and Technical Debt
As more and more pages are added to the project, I found that certain blocks of code are repeated in each.
This is especially true of the data-binding code, which is a copy-and-paste action onto every new page that needs to use controlled components for data entry and modification.
Copy Paste Programming violates the DRY Principle (Don’t Repeat Yourself) and should be considered for refactoring taking into account the Techical Debt introduced with each repitition of the code.
Let’s add a new product listing and editing page to our web app, which will be very similar to our user pages.
The product listing pageThe product editing page
And a snippet of the React javascript that wires up the Product component:
Notice the handleInputChange and handleCheckBoxChange functions, that are exact copies of the same functions in the user controlled component.
There is also some duplication in the handleSubmit function, preventing the default submit action and performing an Ajax call.
I will need this functionality on each web page that contains a controlled component.
As the React documentation explains so simply:
When we want to share logic between two JavaScript functions, we extract it to a third function. Both components and Hooks are functions, so this works for them too!
So let’s pay off some technical debt, and refactor this common code into a custom hook.
A Custom Hook for React data-binding
My first refactoring will look at DRYing up the input change event handlers
Notice that handleInputChange and handleCheckBoxChange only differ on the e.target property that is used to assign the value to state. The second refactoring consolidates the two event handlers into one, the target element type check determining whcih property to use: