IntheinterveningyearsReacthasintroducedit's own solution to cross-cutting state: contexts. They'vealsointroducedReduxlikeAPIs,includingreducers.Infact,muchofReduxcannowbereplicatedpurelyinReactwithjustafewlinesofsupportinglibrarycode.Reacthasalsoimproveditslifecyclehookstomakeworkingwithstateeasier.SonowusingReduxtoimprovecross-cuttingstatemanagementisnolongernecessarysinceReactcanhandlethatitself.
SofromatechnicalstandpointReduxisnolongerneededforwhatmostpeopleuseditforandprojectsthatdon't use it often end up with higher quality code. React can be used in a similar way to Redux now which does mean that it can lead to equally poor state management so maintaining good coding practices is still important. And Redux does still have its uses and can be used to write high quality code it'sjustthatinthepastitwasoftenusedpoorlyandformanyprojectsisnolongernecessary.
Solet's say you run into this point of unoptimization where your app is getting janky and you'vediscoveredthatReactisre-renderingexpensivecomponentsevenwhenthereisnoreasonto,whatcanyoudoaboutit?
EssentiallythismeansthatwhenReactsays"component: please render now"thecomponentchecksitscachetoseeifanypropshavechangedandiftheyhaven'tchangeditreplies"here you go you can just use the result I calculated previously for these components".Reacttakesthatresultandnowtheprocessofrenderingdownthatpartofthetreeiscompletedwithoutanyextraworkbeingdone.
It's important to be aware of how these function though. They perform a shallow comparison of props. This works well in general but if any of your props are arrays, JS objects, or anonymous functions you can run in to cases where you expect your component to be re-rendered but it isn't.Forexample,ifyoupassanarraytoacomponentandthenlateraddanitemtothatarrayyoumightexpectyourcomponenttobere-renderedbutitisn't. This is because React only did a shallow comparison on the array and saw that it was the same array. It doesn'tscanthearraycontents.TogetReacttore-renderyourcomponentwhenyouchangethecontentsofanarrayyouneedtoinsteadreturnanewarray.Thisistrueforothernonprimitives,likeobjects.Ingeneralifyouuse<code>React.PureComponent</code>or<code>React.memo</code>youwillbebetteroffprogramminginapurefunctionalstyle.
Anotherissuetobeawareofwhenusing<code>React.PureComponent</code>or<code>React.memo</code>isthatsometimesyourcomponentwillkeepgettingrenderedevenwhenyouthinkthatitshouldn't be; that none of the props have changed. This is similar to the previous case but in reverse. Instead of you not passing React a new object when you should have been, you pass a prop as a new object every time when you weren'tplanningto.Thisismostcommonlyseenwhenpassingobjectliteralsoranonymousfunctionsasprops.Anobjectliteralgetsinstantiatedintoanewobjecteverytimeitgetsexecuted.Soevenifthecontentsoftheobjectliteralhaven't changed it still creates a new object and React isn'tcheckingtoseeifthecontentshavechangedonlywhetherit'sanewobjectornot.Somakesuretocreatetheseobjectsoutsidetherenderpath.
Whydoesn't React just perform deep checks instead? Well this deep check can lead to bad performance which isn'twhatyouwantwithaperformanceoptimization!
Insummary,ifyourunintoperformancebottleneckswithrenderingthenstartbyusing<code>React.PureComponent</code>or<code>React.memo</code>andprogramminginapurestyle.Whiletherearecaseswheretheyaren't the solutions they are generally a good starting point. I'vewrittenmoredetailedarticlesaboutwhentouseboth<code>React.PureComponent</code>and<code>React.memo</code>.
Alsonotethatweareusingtheselectedlabel'snameasaclassnameinatopleveldiv.Thisallowsustousethewhite-labelingwithourCSSassetsjustbyselectingbasedonthelabelnamelike<code>{`.cars a { ... }`}</code>.
Alsonotethatweareusingtheselectedlabel'snameasaclassnameinatopleveldiv.Thisallowsustousethewhite-labelingwithourCSSassetsjustbyselectingbasedonthelabelnamelike<code>{`.cars a { ... }`}</code>.