Skip to main content

ReactCodemod: An automated approach for refactoring class based components to Hooks

Page 1

ReactCodemod: An automated approach for refactoring class based components

Hooks

React is a popular front end framework for creating online interfaces. With React version 16.8, Facebook has introduced concepts of Hooks and started promoting it as an efficient alternative to class basedcomponents. The current method to convert class based into hooks relies on manual refactoring. This paper proposes reactCodemodanautomated solution for refactoring of class based components to equivalent hooks. ReactCodemod, uses jscodeshift API by Facebook for manipulating of abstract syntax tree. Jscodeshift takes class based react code as input generates an abstract syntax tree, identifies the required code that needs to be refactored using filters and logic runs over the source code, transforms the code by manipulating the abstract syntaxtree. In the end, output code is generated. Output code is equivalent function based code.

Key Words: React.js, Class Based Components, Function BasedComponents,Hooks,Refactoring,Jscodeshift

1.INTRODUCTION

React is the most widely used open source, modern JavaScript library for creating the front end of websites, which comprises web pages, layouts, and content. From version16.8.0Reactisgraduallymovingtowardspopularly knownashooks.Asaresult,therewillbealotofclassbased code that has to be refactored into hooks. The existing approach relies on manual refactoring of class based componentsintoequivalenthookswhichiscumbersomeand timeconsuming.Hencethereisaneedofautomatedsolution to tackle this problem. The proposed method, ReactCodemod, takes react code which consists of class basedcomponentsandneedstoberefactored.FirstanAST willbecreatedforcodebybabel/eslintparserafterthata transform file which contains the filter and logic that manipulatestheASTnodeswillrunoverthesourcecodeand will convert the necessary class based code to function basedcode.ReactCodemodmakesuseofjscodeshiftAPIby Facebook.Therecastandast typespackagesarewrappedin the jscodeshift package. Ast types manages the low level interfacewiththeASTnodes,whereasRecastperformsthe sourcetoASTandbackconversion.Jscodeshiftenablesusto performcomplicatedtransformationsoveralargecodebase in seconds, allowing us to make code changes quickly.

JscodeshiftAPItakessourcecodefileasinputandreplacesit accordingly.Insidetransformsourcecodegetsparsedinto AbstractSyntaxTree.Babelparserisusedforgenerationof AST.TheASTisatree baseddatastructurethatcontainsall thevariables,calls,andflowcontrolstructuresinyourcode. When the application runs, the JavaScript engine iterates throughthetreeandexecutesthecommandsrepresentedby eachnode.AllthetransformationworkisdoneonASTand thenthealteredASTisusedtoregeneratesourcecode.As opposedtomanualrefactoringofreactclass basedcodethis automated approach ReactCodemod looks promising and offersvariousadvantages.Itwillsavedeveloperstimeand effortswhicharerequiredformanualrefactoring[5].

2. LITERATURE SURVEY

Existing class components were refactored into functioncomponents,whichwasthoughttohavesomevalue andtobenecessaryinsomebutnotallcircumstances.While thedevelopersmentionedthebenefitsofrefactoring,suchas increased readability and maintainability, the ability to accommodate new developers unfamiliar with old styles, and more learning resources, their main objection to refactoringcomponentsfromclasscomponentstofunction componentswasalackoftimeandbudget[1].

Thetraditionaltechniqueofrefactoringreactclass basedcomponentstohooksnecessitatesrewritingthewhole codebase,developerswithnecessaryexpertiseofreactand JavaScript,suchascomponents,props,state,context, refs, andtop downdataflow,arerequired.Developersneedsto have understanding of a class without state or lifecycle methods.

Over the course of five years of creating and managing tens of thousands of components, hooks have solved a wide range of seemingly unrelated problems in React.Themainproblemswhichweresolvedbyreleaseof hooksinReactincludesWrapperHell,classesandsideeffect. BeforetheappearanceofReacthooks,therewasnowayto reusethelogicofbehaviortothecomponent.Statefullogicis difficult to reuse between components. Classes make complex components difficult to understand. React class basedcomponentsareeasiertomaintainatinitially,butas the complexity of the class grows, they become

International Research Journal of Engineering and Technology (IRJET) e ISSN: 2395 0056 Volume: 09 Issue: 04 | Apr 2022 www.irjet.net p ISSN: 2395 0072 © 2022, IRJET | Impact Factor value: 7.529 | ISO 9001:2008 Certified Journal | Page3024
to
Shubham Ghule1 , Nikita Aware2 , Nishant Pandey3 , Kiran Mahajan4, Prof. Anant Bagade5 1,2,3,4Dept. Information Technology, SCTR'S Pune Institute of Computer Technology, Pune, Maharashtra, India 5Head of Information Technology, Dept. of SCTR'S Pune Institute of Computer Technology, Pune, Maharashtra, India *** Abstract -

International Research Journal of Engineering and Technology (IRJET)

Volume: 09 Issue: 04 | Apr 2022 www.irjet.net

unmanageable.Classesbecomeunreadableastheygrowand oftenstoredifferentlogicinoneplace.Hooksletyouachieve the same thing by splitting down the logic between components into simple functions that can then be used within the components. Hooks allows extracting stateful logicfromacomponentandallowsindependenttestingand reuse.Reusingstatefullogicwithoutchangingthehierarchy ofitscomponentsismadepossiblebyhooks.Thismakesit easytosharelinksbetweenmanycomponents.Comparing hooks with class based components of equivalent complexity, hooks provide considerably cleaner, easier to understandcomponents.ThiswayReactHooksassistsus inresolvingavarietyofissues.

2.1 ReactJS

ReactJSisaJavaScripttoolkitforcreatingreusable user interface components that is declarative, fast, and adaptable [8]. ReactJs is a component based, open source front endlibrarythat'sjustresponsiblefortheapplication's front end. A ReactJS application consists of several components, each of which is responsible for producing a tiny,reusablepieceofHTMLcode.AllReactappsarebuilt aroundcomponents.TheseComponentsmaybelayeredwith oneothertocreatesophisticatedapplicationsfromsimple buildingblocks[7].

2.2 JavaScript

JavaScript is a text based programming language thatallowsyoutobuildinteractivewebpagesonboththe client and server side. Web browsers and web based applicationsarethemostcommonplaceswhereJavaScriptis used.ReactJSusesJSXwhichisjustasyntacticextensionof JavaScript. JavaScript is also used in metaprogramming. Metaprogramming is a programming method that allows computerprogramstotreatotherProgramslikedata.For the scope of this research jscodeshift toolkit is used for metaprogramming.

2.3 JSX

The abbreviation for JavaScript XML is JSX. It's merelyasyntacticextensionforJavaScript.JSXallowsyouto writeHTML/XML likestructuresinthesamefilewherewe writeJavaScriptcode.(e.g.,DOM liketreestructures),and the preprocessor will turn these expressions into actual JavaScriptcode.JSXtagscontainatagname,attributes,and children,muchlikeXML/HTMLtags.ReactJSheavilyrelies onJSXfordevelopment,allowingustobuildHTMLdirectly inthebrowser(withinJavaScriptcode).

2.4 JScodeshift

TheJscodeshifttoolboxallowsyoutoperformcode mods across several JavaScript or TypeScript files.

ISSN: 2395 0056

ISSN: 2395 0072

Jscodeshiftisarunnerthatappliesthetransformprovidedto each file it receives. Programmers can use the Jscodeshift toolkittoinputabatchofsourcefilesthroughatransform andthenreplacethemwiththeresults.Programmersscan the source code into an abstract syntax tree (AST), make modifications,thenregeneratethesourcecodefromthenew AST.Italsoprovidesasummaryofhowmanyfileshavebeen converted(orhavenot).It’sawrapperforrecastingwitha new API. Recast is an AST to AST conversion tool that attempts to preserve the original code's style as much as possible.

3. METHODOLOGY

Rewriting class based components involves steps like changing class declarations to function declaration, removingconstructors,replacingrenderwithreturn,adding const keyword before all methods, removing this.state throughoutthecomponentandremovingallreferencesto ‘this’throughoutthecomponent.Developershavetospend extra time to do these tasks such as set initial state with useState(), replace compentDidMount with useEffect, replacecomponentDidUpdatewithuseEffect.Allthesetasks aredonebydevelopers,whichcoststimeandefforts[2].

3.1 General Identified Steps for Refactoring

1. Import required hooks we will need in the hook based component.Removetherender()function.

2. Remove state object and replace it with useState hook.

3. AddconstbeforeallclassProperties.

4. Removethis.statethroughoutthecomponent.

5. Remove all references to ‘this’ throughout the component.

6. Replace this.setState with newly defined setter function.

7. Replacelifecyclemethodswiththecorresponding hooks.

Acodemodisapieceofcodethataltersoriginalsourcecode. In this proposed method we are developing a codemod named ReactCodemod based on the same identified steps with the help of metaprogramming libraries. Metaprogrammingisaprogrammingtechniquethatallows computerstotreatothercomputersasdata.Itmeansthata program may be designed to read, produce, generate, or convertother programsas well asmodify itself whileit is running[3].Therearevariouslibrariesavailablewhichare helpfulfordevelopingcodemods.Thetwopopularoptions arenamelycombyandjscodeshift.Forthiscodemodweare usingjscodeshiftbecausecombyismoregenerallibraryfor convertingcodesfromvariouslanguages,jscodeshiftismore focused towards building codemods. It is a toolkit for running codemods over multiple JavaScript or TypeScript files. Jscodeshift includes a runner that runs the supplied

e
p
© 2022, IRJET | Impact Factor value: 7.529 | ISO 9001:2008 Certified Journal | Page3025

International Research Journal of Engineering and Technology (IRJET) e ISSN: 2395 0056

Volume: 09 Issue: 04 | Apr 2022 www.irjet.net p ISSN: 2395 0072

transformoneachfileitreceives.Italsoshowsthenumber offilesthathaven'tbeenupdated.Awrapperforrecastthat exposesanalternativeAPI.Recastisanabstractsyntaxtree toabstractsyntaxtreetransformtoolthattriestopreserve asmuchofthecurrentcode'sstyleaspossible.Jscodeshiftis atoolbox.Itcombinesavarietyofparsers,asttypesfornode construction,andrecastforpretty printingtoassurecode that follows particular formatting constraints. It neatly bundles these tools and gives a cohesive API for finding, filtering, mapping, and replacing the AST nodes. It also containsarunnerfeaturethatallowsthousandsoffilestobe transformedatonce.

4. SYSTEM ARCHITECTURE

Reactcodemodletsyouperformatransformonaset ofclassbasedsourcefilesandreplacethemwiththeresults. You parse the source into an abstract syntax tree (AST), changetheASTaccordingtothefilters,andthenbuildthe hook based source file from the updated AST within the transform.

contentsofthefile,whilethepathreferstoitslocation.The transform module's jscodeshift api object has three properties: jscodeshift, stats, and report. Jscodeshift is a jQuery likeASTnavigationandtransformationAPI.Statsis a dry run function that reports the number of times a certain value has been called; this data is important in transformation. The report command prints a string to stdout, which may then be used by other applications. Optionstoresalltheoptionsgiventotherunner,enabling theusertogivethetransformmorepossibilities.Thestate ofthetransformationisdeterminedbythevaluereturned from the Transform Module. The transformation was successfulifthereturnvaluedifferedfromthefileprovided toit;ifthereturnvaluewasthesameastheoriginalfile,the transformation failed. If the Transform module returns nothing,thetransformationisconsideredsuccessful.

Fig. 1: ReactCodemodBlockDiagram

Reactcodemod achieves the transformation of class based components to hook based components using jscodeshift libraryandperformsfollowingsteps:

1. GenerateanAbstractSyntaxTree(AST)fromgiven reactsourcefile.

2. TraversetheASTandlookoutformatches.

3. MaketheappropriatechangestotheAST.

4. Regeneratethesourcefilewithfunctionbasedcode.

Jscodeshift is the refactoring tool, created by Facebook. It allowsustorunReactCodemodacrossdifferentdocuments. Jscodeshiftisastraightforwardandsimpleto utilizeAPIthat is controlled by Recast. Recast is an AST (Abstract Syntax Tree)toAST(AbstractSyntaxTree)refactoringtool.

4.1 Transform Module

The transform module just exports a function. The fileinfo, api, and options parameters are accepted by the transformmodule.Thelocationandsourceofthefiletobe handledareincludedinFileinfo.Thesourcerelatestothe

Fig. 1: ReactCodemodArchitecture

4.1.1. Parser

Jscodeshift can pick a parser to parse the source file usingthistransform.Transformmoduleexportsnameofthe parserasastring,whichcanbe"babel","stream","Babylon", "tsx","ts",orsomeotherparsercompatiblewithrecast.In the transformation module, several architectural components,andnotionsofrecastandJavaScriptareused.

4.2. Abstract Syntax Tree

Thegivencodeisconvertedtoanabstractsyntaxtreeby theJavaScriptengine.TheASTisatree baseddatastructure thatrepresentsthecode'svariables,calls,andflowcontrol structure.

© 2022, IRJET | Impact Factor value: 7.529 | ISO 9001:2008 Certified Journal | Page3026

International Research Journal of Engineering and Technology (IRJET)

4.2.1 AST Nodes

AJavaScriptobjectwithadefinedsetoffieldsisknown asanASTNode.Thetypeofanodeisthemostcommonway toidentifyit,butitalsohasanumberofadditionalvariables thathelptoidentifyit.

4.2.2 Path Objects

Every AST Node has a wrapper object that specifies a method to traverse the AST. Paths also contain meta data and processing assistance methods for AST nodes. To traverse the tree up AST nodes, path objects must have enough information about parent nodes to enable an excellentnodeiterationandtraversalmechanism.

4.2.3 Collections

Jscodeshiftisconstructedaroundtheideaofcollectionof paths. a collection has strategies to process the nodes internal a collection that often leads to a new collection. Collectionsaretyped which means method defined for one type of collection will not work on any other type of collection.

4.3 Extensibility

ISSN: 2395 0056

ISSN: 2395 0072

code = code.replaceAll("this.", ""); return j(code).toSource(); }

Output

import React, { Component } from "react"; class Three extends Component { state = { year: 1995, type: "Mercedes", used: true, }; render() { return ( <div> <ul> <li>{state.year}</li> <li>{state.used ? "Used Car" : "Brand New!"}</li> </ul> </div> ); } }

5.2 Class declaration to function declaration

Input

JscodeshiftprovidesAPI

extend

astomake transformsmorereadable.Thetwoformsofextensionsare generic extensions and type specific extensions. Generic extensionsdonotworkwithnodedataandinsteadtraverse thewholecollection,whereasType specificextensionsonly workwithaparticularnodetype.

5.1 Remove

Input

import React, { Component } from "react"; class Three extends Component { state = { year: 1995, type: "Mercedes", used: true, }; render() { return ( <div> <ul> <li>{this.state.year}</li> <li>{this.state.used ? "Used Car" : "Brand New!"}</li> </ul> </div> ); }

Transform code

export default function transformer(file, api) { const j = api.jscodeshift; let code = file.source;

class App extends Component { handleClick = () => { console.log("Hello World!"); } }

Tranform code export default function transformer(file, api) { const j = api.jscodeshift; const root = j(file.source); const { statement } = j.template; root.find(j.ClassDeclaration).replaceWith((p) => { return statement`function ${p.value.id.name} () {

${p.value.body.body} }`; }); return root.toSource(); }

Output function App() { handleClick = () => { console.log("Hello World!"); };

6. CONCLUSION

ThispaperproposedamethodthatmanipulatestheASTof theclass basedcodewritteninJSXandconvertsitintoan equivalenthook basedcomponentbymanipulatingtheAST of the code using jscodeshift. As a result of applying proposed method, we found that the AST of the existing class basedcomponentcanberedesignedandmanipulated

e
Volume: 09 Issue: 04 | Apr 2022 www.irjet.net p
© 2022, IRJET | Impact Factor value: 7.529 | ISO 9001:2008 Certified Journal | Page3027
to
collections
5. EXPERIMENTAL RESULTS
‘this’ keyword 
} 
}

International Research Journal of Engineering and Technology (IRJET) e ISSN: 2395 0056

Volume: 09 Issue: 04 | Apr 2022 www.irjet.net p ISSN: 2395 0072

into an equivalent hookbased component. We also found thatthismethodmaynotworkinallcasesbutwillsurely reduce the efforts of anyone doing transformations manually which in turn will save time and efforts of the person using this tool. As React is gradually promoting hook basedcomponents,itwillbebeneficialasitisreducing humaneffortsandincreasingefficiencyofwork.

ACKNOWLEDGEMENTS

ThisworkwasdoneundertheKrixiIdeasandTechnology Solutions mentorship program. We would like to express ourgratitudetowardsourmentorsMrPankajLagu,Director Product Strategy and Mr Tejas Joshi at Krixi Ideas and Technology Solutions for their continuous support and encouragement.

REFERENCES

[1]TuomasLuojus,”Usabilityandadaptationofreacthooks” ,April2021.

[2] Daniel Bugl, ”Learn react hooks: build and refactor modernreact.jsapplicationsusinghooks”,October2019

[3]RobertasDamaˇseviˇcius,VytautasˇStuikys,”Taxonomy of the fundamental concepts of metaprogramming” , 2008.

[4]MohitThakkar,”UnitTestingUsingJest”,April2020.

[5] Emerson Murphy Hill, Chris Parnin, and Andrew P. Black, ”How WeRefactor, and How We Know It”, February2012.

[6]JaehyunKim,YangsunLee,”AStudyonAbstractSyntax Tree forDevelopment of a JavaScript Compiler” , June 2018.

[7]ArshadJaveed,”PerformanceOptimizationTechniques forReactJS”,2019

[8] Sanja Delcev, Drazen Draskovic, ”Modern JavaScript frameworks:ASurveyStudy”,August201.

© 2022, IRJET | Impact Factor value: 7.529 | ISO 9001:2008

|

Certified Journal
Page3028

Turn static files into dynamic content formats.

Create a flipbook