<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
<channel>
<title>divjot — blog</title>
<link>https://bogas04.fyi</link>
<description>My thoughts on work, life and world.</description>
<language>en-us</language>
<atom:link href="https://bogas04.fyi/blog.xml" rel="self" type="application/rss+xml" />
<lastBuildDate>Wed, 19 Aug 2026 17:48:05 GMT</lastBuildDate>
<item>
<title><![CDATA[I was wrong about weight loss]]></title>
<link>https://bogas04.fyi/blog/2026/08/i-was-wrong-about-weight-loss</link>
<guid>https://bogas04.fyi/blog/2026/08/i-was-wrong-about-weight-loss</guid>
<pubDate>Sat, 15 Aug 2026 10:31:03 GMT</pubDate>
<description><![CDATA[You might have read my previous blog about losing 15kg from a decade back, looking back I now realize I missed this one trick clickbaitpromax]]></description>
<content:encoded><![CDATA[<p><a class="blog-image-link" href="https://bogas04.fyi/img/blog/1__AW6KCuaBBSUSWKu8dIrmLA.png" target="_blank" rel="noopener noreferrer"><img src="https://bogas04.fyi/img/blog/1__AW6KCuaBBSUSWKu8dIrmLA.png" alt="A picture showing downward trend of my body weight from 90kg to 69kg over few months, a decade ago"></a></p>
<p>Look at that trend line baby, mm-hmm! I am just as amazed as I was a <a href="https://bogas04.fyi/blog/2017/07/my-15-kg-weight-loss-journey/">decade ago</a> when I lost roughly 20kg by maintaining a calorie deficit. It was truly magical for someone who was overweight and obese throughout their childhood. It became a defining feature of my self, something the chatter in my brain would keep affirming.</p>
<p>A decade later, after having maintained that weight, gained it back twice, and lost it again, I have more thoughts on the topic. I feel I was entirely missing a very important aspect, and I would like to revise my position.</p>
<p>There's the mechanics of weight loss, which undoubtedly remains to be a calorie deficit, and then there's the humanity of weight loss, which is often overlooked. A decade later, we have weight loss drugs that essentially "cure" the "illness" of hunger, which definitely work on a mechanical level by simply reducing the calories consumed more than your maintenance needs, but it too, I feel, mistakes hunger for the illness, so to speak.</p>
<p>The real question is not how to lose weight, because today we already have a pill for that, or of course insights from my old blog post, but it is to understand why we feel insatiable hunger and exceed our BMR so easily in the first place? How was I able to overcome it multiple times in the last 10 years? Why was I unable to maintain that and ended up gaining weight back? From normal BMI to obese?</p>
<p>This is exactly what I feel I missed back then, and was forced to confront. This can be a question with a unique answer for everyone, for brain, gut, and hormones are literally not fully understood. However, there are some hypotheses you could have, hormones? obesogenic world? toxic relationships? For me, it was the modern hobby we all share.</p>
<h2 id="stress"><a class="heading-permalink" href="https://bogas04.fyi/blog/2026/08/i-was-wrong-about-weight-loss#stress" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text">stress</span></a></h2>
<p>Yup. The final boss of most maladaptive behaviors. In my case, the stress is what kept me away from doing the things that guarantee a calorie deficit. You may really optimize every ingredient to be low in calorie density, remove all snacks from your pantry, switch to zero oil or sugar free alternates, but the underlying stress is what made me order a 12-inch pizza at night, quickly stuff embarrassingly huge portions of leftovers straight from the fridge over the sink before even plating or heating it. What brought out this "illness" in me was not lack of understanding of a calorie deficit, but underlying stress. My body was screaming for help. If this feels familiar, it may be worth seeking support. Ironically, the stress of maintaining a calorie deficit in such a state only fuels the stress, so you'll find yourself burned out after a few weeks of diet or gym.</p>
<p>What worked for me a decade ago was the fact that I had moved 2000 kms away from home, which could usually trigger stress, but thanks to my <em><a href="https://bogas04.fyi/blog/2021/03/how-holi-is-related-to-narcissism-and-patriarchy/">colored</a> <a href="https://bogas04.fyi/blog/2026/07/unusual-feelings-evoked-by-music/">childhood</a></em>, it actually suddenly calmed my nervous system. On top of that, I had joined a new job where I felt overqualified, with a commute of a 10-minute walk, albeit with a <a href="https://maps.app.goo.gl/CU55D29fUVq85SYb6">dreadful road crossing</a> (remember folks, <strong>India is not for beginners</strong>). I also had free time to devote to 3 hour-long walks, access to office canteen's affordable and healthy breakfasts and lunches, and still having enough time to cook my own meals. Imagine the luxurious life I was living back then? The 30s me just dreams of that.</p>
<h2 id="so-what-changed"><a class="heading-permalink" href="https://bogas04.fyi/blog/2026/08/i-was-wrong-about-weight-loss#so-what-changed" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text">so what changed?</span></a></h2>
<p><a class="blog-image-link" href="https://bogas04.fyi/img/blog/weight-journey-2016-2026.webp" target="_blank" rel="noopener noreferrer"><img src="https://bogas04.fyi/img/blog/weight-journey-2016-2026.webp" alt="2016-2026 weight trend"></a></p>
<p>I was able to maintain my weight for a good half-decade 2017-2022, but late 22 to 26 have been quite chaotic. As I am writing, I can already remember some major life events that caused bursts of stress, be it the dark clouds of <a href="https://layoffs.fyi/">layoffs in the tech industry</a>, my individual discovery of self, the infliction of 30 revolutions around the sun (how does one suddenly start getting injured doing absolutely nothing?) and some major shifts in relationships. That's an enormous amount of stress, that the 20-something me could never have imagined enduring.</p>
<p>These were fires that I needed to fight, as opposed to the second favorite hobby of us all, avoidance. As these got addressed, it became easy to focus on weight loss/muscle gain/health in general. I implore you to focus on these two world-famous hobbies of stress and avoidance, and take it easy even if your diet is not "working". The mechanism might not be faulty, the environment might be, the self that the environment or the mechanism is happening to might just not be in sync.</p>
<h2 id="tldr-please"><a class="heading-permalink" href="https://bogas04.fyi/blog/2026/08/i-was-wrong-about-weight-loss#tldr-please" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text">tldr please?</span></a></h2>
<p>I <a href="https://bogas04.fyi/blog/2017/07/my-15-kg-weight-loss-journey/">wrote</a> about a simple understanding of a calorie deficit and immediately benefiting from it a decade ago, but what I missed was how stress-free my life was, which allowed me to maintain a calorie deficit for years going forward. But life in my 30s brought various anxieties and reflections that made it hard to achieve a deficit. My challenge is anxiety control, not calorie control.</p>
]]></content:encoded>
</item>

<item>
<title><![CDATA[Forgive me father for I have vibed]]></title>
<link>https://bogas04.fyi/blog/2026/08/forgive-me-father-for-i-have-vibed</link>
<guid>https://bogas04.fyi/blog/2026/08/forgive-me-father-for-i-have-vibed</guid>
<pubDate>Sat, 15 Aug 2026 06:02:13 GMT</pubDate>
<description><![CDATA[I cured poison with poison to cope with my own anxieties better]]></description>
<content:encoded><![CDATA[<p>So this is my entry to a prompt "Write about a system you built for your life you are very happy with" I got at <a href="https://indieweb.org/Bangalore">an Indie Web Meetup</a>.</p>
<p>So, I vibe coded a todo app? <strong>Yay, big deal</strong>. No seriously, this is definitely a big deal for me, or was when I was suffering through what I feel was the biggest anxious phase of my life.</p>
<h2 id="anxiety"><a class="heading-permalink" href="https://bogas04.fyi/blog/2026/08/forgive-me-father-for-i-have-vibed#anxiety" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text">anxiety</span></a></h2>
<p>This year sucks. Apart from wars, war crimes, loss of life, financial uppending by an orange fart ball, <a href="https://bogas04.fyi/blog/2026/08/the-new-crysis-of-video-gaming/">gaming industry crisis</a>, human-caused "natural" disasters, I personally also suddenly felt a historically famous, crisis of purpose. AI Agents have indeed become so good that with enough tokens and relevant context, you can indeed get them to build you whatever software you want. I really felt the pain of being perceived as irrelevant and redundant, despite still having a job (so far) and having institutional knowledge. Not to toot my own horn but I <a href="https://bogas04.fyi/#talks">spoke publicly</a> about cool stuff we did at Swiggy and what not. It was very easy to go into spirals of "but then what's the point of it when it can be done by a prompt".</p>
<p>I had briefly read about a talk by a fellow member of the tech community talking about <a href="https://www.linkedin.com/posts/poojabhaumik_in-this-talk-i-coined-a-new-term-ego-coding-activity-7322124840600043521-_Dsc/">ego coding
</a> and without even viewing it, I felt immense pain even thinking about the title. I was indeed suffering from "Ego coding" blues. I wanted MYSELF to write code, and now indeed AI was sometimes, not always, better or faster than me. I was in despair and had lost any will to do anything.</p>
<p>One of my colleagues at work had a different response to this dread. They immersed themselves in work, did so much in a day that one would usually do over a month thanks to this agentic superpower. Man I was super scared to open slack and see their multiple PRs in a day with beautiful screenshots of before/after. It didn't look sloppy, it wasn't coded in a sloppy way either. It was literally their blood, sweat, tears and tokens.</p>
<h2 id="wait-where-is-this-going"><a class="heading-permalink" href="https://bogas04.fyi/blog/2026/08/forgive-me-father-for-i-have-vibed#wait-where-is-this-going" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text">wait, where is this going?</span></a></h2>
<p>Yeah, so amidst all this, therapy was one place for me to understand why suddenly I had the urge to become a driver, or open up a cafe with my savings, or buy a fleet of cabs and earn my living that could be protected from AI. Now I am not trying to tell you I have cured my anxiety, for it often is a signal of some other underlying fears, but I want to talk about a system that helped me calm down a bit, put my head down and focus on getting work done. This is a coping mechanism, not the ultimate fix.</p>
<h2 id="a-todo-app"><a class="heading-permalink" href="https://bogas04.fyi/blog/2026/08/forgive-me-father-for-i-have-vibed#a-todo-app" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text">a todo app?</span></a></h2>
<p><a class="blog-image-link" href="https://bogas04.fyi/img/blog/day-planner-app.webp" target="_blank" rel="noopener noreferrer"><img src="https://bogas04.fyi/img/blog/day-planner-app.webp" alt="Screenshot of the todo app"></a></p>
<p>So to fight the daemon of anxiety triggered by AI, I used AI to create a todo app, like one does. Now this wasn't an ordinary todo app, it was something I really wanted for myself. I wanted to have a list of things I want to do today and see the progress <em>I</em> made, not in comparison to my peers, or the world at large, just what wasn't done at the start of the day, and was indeed done by the end. I also wanted to perceive movement which was getting dimmed in the noise of work slack and doom posts of reddit. So I wanted to write a sentence or two about my reflections of the day, and a rating. Some days were 1/10, some were 9/10, and this granularity helped me answer the loud critic in my head asking me "what have you done?".</p>
<p>I (asked the LLM to write) wrote it in Swift, even though I have 0 clue about how that language works. I wanted it for my mac using mac aesthetics, I didn't want to run electron, so Swift it was. Honestly, I had no cognitive batteries to really learn anything new or do anything, but I wanted a wonky gratitude journal that I would actually use.</p>
<p>I also wanted to have pictures of Marianne North, after being enamored by her art as seen in <a href="https://bogas04.fyi/#travel">Kew Gardens</a>. So I got it added too. These calmed me.</p>
<p>BTW, can we just talk about how cool and uber rich Marianne North was? Like she/they traveled 6 continents in her/their 40s, creating immense art and pursuing botany. Why can't the rich of 21st century do that instead?</p>
<p><a class="blog-image-link" href="https://bogas04.fyi/img/day-planner-break.webp" target="_blank" rel="noopener noreferrer"><img src="https://bogas04.fyi/img/day-planner-break.webp" alt="a 20 minute break reminder"></a></p>
<p>I then also added more features to it, a 20-minute break reminder to do my ergonomic exercises, a sound mixer coz why not, and so on.</p>
<h2 id="does-it-work"><a class="heading-permalink" href="https://bogas04.fyi/blog/2026/08/forgive-me-father-for-i-have-vibed#does-it-work" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text">does it work?</span></a></h2>
<p>I have been using it almost daily, and my daily ratings have definitely improved. I was able to manage my catastrophizing mind, and get things done, irrespective of what my environment felt about it.</p>
<p>It also surprisingly did something different, it also helped me understand what vibe coding can actually feel like. I would never have been able to learn Swift, code the app the way it is, or build all these features overnight, in fact I doubt I would be able to do it using electron either, with this polish or at this pace. It helped me truly experience parts of <a href="https://xcancel.com/karpathy/status/1886192184808149383?lang=en">this tweet</a>, especially the "embrace exponentials". I really understood the devil I was fighting better, and came to some level of acceptance of the new reality. Life is about change, and change is painful, and change also becomes the new normal.</p>
<p>Also, I am sure anyone could vibe code a Swift app, or I could've built this app with enough time and cognitive resources. But something tells me, there is still some degree of analytical and problem-solving skill required to get to a desired end state. To describe a problem and convince a machine to solve it via lexicography doesn't really change, be it tyop rieeden sklloppy engrish or sophisticated arcane assembly language. (No this post is not sponsored by your favorite ClosedThropicPilot, ain't nobody paying me to shill).</p>
<h2 id="fin"><a class="heading-permalink" href="https://bogas04.fyi/blog/2026/08/forgive-me-father-for-i-have-vibed#fin" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text">fin</span></a></h2>
<p>I feel less anxious now, I am able to work a bit more peacefully, and I see agentic coding as yet another form of coding, where the syntax is high level system design. Therapy did most of it, this todo app helped a bit, and the rest was growing pains.</p>
]]></content:encoded>
</item>

<item>
<title><![CDATA[The new crysis of video gaming]]></title>
<link>https://bogas04.fyi/blog/2026/08/the-new-crysis-of-video-gaming</link>
<guid>https://bogas04.fyi/blog/2026/08/the-new-crysis-of-video-gaming</guid>
<pubDate>Sun, 02 Aug 2026 00:00:00 GMT</pubDate>
<description><![CDATA[My hobby is under threat yet again and that worries me]]></description>
<content:encoded><![CDATA[<p>NOTE: I am not an analyst, just a gamer who consumes media on gaming and has some spit balling to share.</p>
<p><a class="blog-image-link" href="https://bogas04.fyi/img/blog/need%20for%20speed%20underground%20on%20ROG%20Ally.jpg" target="_blank" rel="noopener noreferrer"><img src="https://bogas04.fyi/img/blog/need%20for%20speed%20underground%20on%20ROG%20Ally.jpg" alt="abandonware need for speed underground on ROG Ally"></a></p>
<blockquote>
<p><em>Me playing NFS Underground 2 on ROG Ally, a game that is delisted and abandoned by original publisher</em></p>
</blockquote>
<p>I feel incredibly privileged to have been born into a time when video games existed, and to witness their maturity from Pong to pixel art to 3D graphics, and now seamless open worlds with incredibly detailed graphics and interconnected systems. Video games have always pushed hardware to its limits, whether in sound, storage, display, visual trickery, or even immersive narratives.</p>
<p>However, word on the street is that the gaming industry is dying. Never before have we seen layoffs at both successful and unsuccessful studios. Developers and contract workers are rewarded with layoffs, while executives flaunt <a href="https://www.yahoo.com/news/former-bungie-devs-show-fury-154256800.html">their luxury car collections</a>. Gamers are playing the same old games, and the top 10 have remained remarkably persistent, whether they are live-service games such as Fortnite, Roblox, and GTA Online, or remasters and remakes.</p>
<p>The fact that we have gone through almost three console generations without a new GTA says a lot about how expensive new games have become to make, and how reluctant mega-studios have grown after seeing the popularity of games-as-a-service. Estimates put GTA Online's average revenue at about $1.3 million a day; most new games fail to reach anything close to that. Cough Concord, cough Highguard, cough Redfall.</p>
<p>While this has been true for quite some time, a new challenger is on the block: an AI-induced hardware crisis. Suddenly everyone wants to build data centres, making everything with RAM or a CPU incredibly expensive. New gamers may stick with their existing devices, or buy fewer games after paying for an expensive console or PC wrapped around RAM and storage.</p>
<p>Analysts worry about sales of the PS6 or the next Xbox Series Z One X Two XTZ. Even Valve has struggled to offer the Steam Machine, a machine much less powerful than a PS5, at a lower price than the PS5.</p>
<p>If you were feeling concerned already, fear not: there is much more to be afraid of. Sony, one of the few <a href="https://www.youtube.com/watch?v=kWSIFh8ICaA">bastions of physical games</a>, has reliably shipped games on its discs, unlike Xbox, for which there is a <a href="https://www.doesitplay.org/">community-crowdsourced site</a> to check whether a disc actually contains a playable game. Yet Sony has announced that it will repurpose its Austrian factory to make microlenses for, you guessed it, data-centre equipment. It chose a fantastic time to announce this: after <a href="https://www.pcmag.com/news/love-terminator-2-playstation-network-deletes-500-plus-movies-for-uk-users">delisting more than 500 digital movies for UK users without refunds</a> and amid <a href="https://www.msn.com/en-in/news/insight/sony-to-end-playstation-physical-discs-in-2028-sparks-backlash/gm-GM768C6A12?gemSnapshotKey=GM768C6A12-snapshot-1&amp;uxmode=ruby">reports that PlayStation physical discs could end in 2028</a>.</p>
<p>Surely you think that's pretty much it. Well, no: Nvidia and AMD have recently announced price hikes, and even Apple, with its insanely good MacBook Neo, is going to raise prices and we might be even looking at <a href="https://www.tomshardware.com/laptops/macbooks/apple-launches-official-program-for-leasing-macs-as-ai-price-crunch-bites-24-and-36-month-leasing-options-provided-by-klarna">financing options</a> for its cheapest laptop soon too.</p>
<p>Let's talk a bit about Nvidia. It has single-handedly ensured that every game is DLSS-pilled with RTX technologies, and has normalised terrible GPU pricing with lopsided VRAM. While it profiteers massively from the AI boom with one hand, it offers a state-of-the-art streaming option with the other: GeForce NOW, at the measly price of ₹2,000 per month. I gave it a shot, and it is insanely good, so good that I am afraid we are headed towards digital-only, cloud-based gaming bundled into a subscription. Surely everyone will otherwise be priced out.</p>
<p>So what does this mean? Will you be able to afford your gaming hobby, or will you own nothing and be happy? To be fair, there is something to be said about the rise of indie games. They now frequently receive Game of the Year nominations (<a href="https://trello.com/c/ycWwpClN/271-clair-obscure-expedition-33">Clair Obscur Expedition 33</a>, my personal favorite while not truly an indie, it is definitely not a Rockstar/Sony/Ubisoft-esque blockbuster game), and even win them, while often costing much less than the standard $70 AAA release. Some run beautifully on older hardware; heck, some are designed with web technologies and get mobile ports too. <a href="https://www.rockpapershotgun.com/vampire-survivors-interview-creator-wanted-something-to-play-at-the-weekend">Vampire Survivors is a good example of that spirit</a>.</p>
<p>It certainly feels like a big reset moment: a transitional phase driven primarily by enshittification and the AI boom. I am not very hopeful about the future, but when I look at my backlog, I feel grateful to the developers of the past who put their time and energy into making these games.</p>
<p>Maybe finally video games might only be made because the <a href="https://www.brainyquote.com/quotes/todd_howard_986086">developers want to play them</a>, not <a href="https://www.youtube.com/watch?v=5U1_qzYsh_U">only to sell them</a>, but going through this Crysis is the price we might pay to learn that lesson.</p>
]]></content:encoded>
</item>

<item>
<title><![CDATA[Unusual feelings evoked by music]]></title>
<link>https://bogas04.fyi/blog/2026/07/unusual-feelings-evoked-by-music</link>
<guid>https://bogas04.fyi/blog/2026/07/unusual-feelings-evoked-by-music</guid>
<pubDate>Sat, 18 Jul 2026 11:20:20 GMT</pubDate>
<description><![CDATA[On learning to let yourself enjoy the bliss of subjectivity]]></description>
<content:encoded><![CDATA[<p>So this is my entry to a prompt "Write about an album that got you through a hard time" I got at <a href="https://indieweb.org/Bangalore">an Indie Web Meetup</a>.</p>
<p>Without thinking much, my mind instantly thought about my unusual relationship with the music I've been listening to lately. I firmly believe that our choice in music reveals multiple layers about our experiences.</p>
<p>Our choice of music is never objective, there are no objectively perfect lyrics, objectively melodious melodies, objectively perfect cacophony of vibrations and precurssions that can soothe every human mind, at all times. In fact, you'd find people change their taste over the years in unrecognisable ways. For no development of taste in music is also objectively predetermined. Not all roads lead to Jazz.</p>
<p>With this perspective, the question arises why then one chooses to prefer certain music, and why do they prefer to change that taste over life experiences? This blog is my answer to these questions.</p>
<p>I've been raised in a rather orthodox atmosphere of obedience, subservience, unquestionable loyalty, and an unpayable debt towards your parents. The kind of climate where things were either Godly good or Evilly bad, and doing bad things meant you, a child, figuring out this complex world, are bad, disgrace and worthy of abuse.</p>
<p>What does a <em>fairly straightforward</em> upbringing like this, though highly lucrative in psychotherapy spheres,  does to the taste of music of a growing human mind?</p>
<p>Naturally, in this very monochromatic world, the cosmic dance of vibrations and the fractal strings of alphabets, becomes objective.</p>
<p>Not only the child develops an <em>acceptable</em> taste in music, and seeks out music that <em>earns</em> validation in the eyes of their caretakers, peers, and every single person they want to impress, silently, a very loud playlist gets developed that the child subjectively enjoys but tries very hard to hide by objectively looking down at people who like such music.</p>
<p>With this background, as I was recovering from what seemed to be fever after a fall from bike on slippery curvy hilly roads of sleeper town of Munduk in Bali, a day before Nyepi, the auspicious Hindu festival of silence, when even airports are shut and almost no hotels provide any service, turned out to be actually entirely unrelated to the fall, and was simply the worst fever I've ever had, for it was the first sign of a very common viral infection of dengue.</p>
<p>In such a catatonic state, the guards of that child lowered, and he finally allowed to be soothed with the music that the algorithm kept recommending but he kept avoiding it coz he learned to believe it was objectively bad music.</p>
<p>And soothed he, the child, was. He can't explain why he loves this music, it makes his stoic persona want to dance, it makes him happy even though the lyrics are far from his acquired personality, but he feels an unexplainable connection to it which his objectivity cannot rationalize.</p>
<p>And that's how I got through a hard time, by learning to let that child enjoy the bliss of subjectivity.</p>
]]></content:encoded>
</item>

<item>
<title><![CDATA[How we fixed a 2-second React Native stutter at udaan]]></title>
<link>https://bogas04.fyi/blog/2025/07/how-we-fixed-a-2-second-react-native-stutter-at-udaan</link>
<guid>https://bogas04.fyi/blog/2025/07/how-we-fixed-a-2-second-react-native-stutter-at-udaan</guid>
<pubDate>Wed, 30 Jul 2025 00:00:00 GMT</pubDate>
<description><![CDATA[A small, careful debugging effort that made a painful interaction feel responsive again.]]></description>
<content:encoded><![CDATA[<p><a class="blog-image-link" href="https://bogas04.fyi/img/blog/udaan-react-render-stutter.png" target="_blank" rel="noopener noreferrer"><img src="https://bogas04.fyi/img/blog/udaan-react-render-stutter.png" alt="React Native re-rendering investigation"></a></p>
<p>I recently wrote about one of the more satisfying debugging efforts I have been part of at udaan: <a href="https://medium.com/engineering-udaan/how-we-solved-a-2s-stutter-caused-by-re-rendering-react-components-5b852ca1852a">how we solved a 2s+ stutter caused by re-rendering React components</a>.</p>
<p>The problem looked deceptively small: tapping Add to Cart could leave the UI visibly stuck for more than two seconds. The fun part was getting from that symptom to the underlying cause without turning the fix into a rewrite.</p>
<p>We used simple visual measurements to see the repeated renders, then narrowed the blast radius with smaller hooks, selectors, and batching. Each change was surgical: reduce the work that was actually happening instead of papering over it with a loading state or a new state-management migration.</p>
<p>The result was a much smoother interaction and a reminder I keep coming back to: performance debugging gets much easier once the measurement is concrete enough to make the bottleneck obvious.</p>
<p>Read the full story on <a href="https://medium.com/engineering-udaan/how-we-solved-a-2s-stutter-caused-by-re-rendering-react-components-5b852ca1852a">udaan engineering</a>.</p>
]]></content:encoded>
</item>

<item>
<title><![CDATA[What startup performance at udaan taught me]]></title>
<link>https://bogas04.fyi/blog/2023/08/what-startup-performance-at-udaan-taught-me</link>
<guid>https://bogas04.fyi/blog/2023/08/what-startup-performance-at-udaan-taught-me</guid>
<pubDate>Tue, 15 Aug 2023 00:00:00 GMT</pubDate>
<description><![CDATA[A React Native performance investigation about telemetry, experiments, and choosing simpler fixes.]]></description>
<content:encoded><![CDATA[<p><a class="blog-image-link" href="https://bogas04.fyi/img/blog/udaan-react-native-startup-performance.jpg" target="_blank" rel="noopener noreferrer"><img src="https://bogas04.fyi/img/blog/udaan-react-native-startup-performance.jpg" alt="React Native startup performance investigation"></a></p>
<p>I also wrote about a much more persistent problem at udaan: <a href="https://medium.com/engineering-udaan/reacting-to-change-tale-of-a-web-developer-improving-startup-performance-for-a-large-react-native-854f8a4850fd">improving startup performance for a large React Native app</a>.</p>
<p>Startup performance is an awkward problem because the first question is usually not “how do we fix it?” but “what exactly are we measuring?” The investigation taught me the value of useful telemetry, small experiments, and being honest when the data contradicted an appealing explanation.</p>
<p>It was tempting to reach for a shiny migration or a sweeping upgrade. Instead, the valuable work was simplifying the startup path, validating one hypothesis at a time, and paying attention to how the app <em>felt</em> as well as what the numbers reported.</p>
<p>That approach made the work less glamorous, but much more reliable. It is a lesson I now carry into most performance work: simplify first, measure the change, and earn the complexity only when it is necessary.</p>
<p>Read the full story on <a href="https://medium.com/engineering-udaan/reacting-to-change-tale-of-a-web-developer-improving-startup-performance-for-a-large-react-native-854f8a4850fd">udaan engineering</a>.</p>
]]></content:encoded>
</item>

<item>
<title><![CDATA[How Holi is related to narcissism and patriarchy]]></title>
<link>https://bogas04.fyi/blog/2021/03/how-holi-is-related-to-narcissism-and-patriarchy</link>
<guid>https://bogas04.fyi/blog/2021/03/how-holi-is-related-to-narcissism-and-patriarchy</guid>
<pubDate>Mon, 22 Mar 2021 06:02:13 GMT</pubDate>
<description><![CDATA[My views on emotional abuse done by narcissistic parents and how the epic of Bhagat Prahlad relates to it.]]></description>
<content:encoded><![CDATA[<h2 id="originally-a-twitter-thread"><a href="https://bogas04.fyi/blog/2021/03/how-holi-is-related-to-narcissism-and-patriarchy#originally-a-twitter-thread" aria-hidden="true" tabindex="-1"><span>🔗</span></a>Originally a <a href="https://twitter.com/i/status/1373926490279178245">Twitter Thread</a>.</h2>
<p>With Holi coming up and me witnessing a lot of turmoil in my personal life, I was forced to think about Holi in a very specific way. At risk of over-simplifying and appropriating the narrative, here are my unpopular views on the epic of Bhagat Prahlad and how it relates with <a href="https://www.psychologytoday.com/us/blog/victim-victor/202011/is-how-narcissists-think">narcissism</a> and toxic <a href="https://www.psychologytoday.com/us/blog/acquired-spontaneity/201708/why-patriarchy-is-not-about-men">patriarchy</a>.</p>
<p><a class="blog-image-link" href="https://bogas04.fyi/img/blog/prahlad-1.jpg" target="_blank" rel="noopener noreferrer"><img src="https://bogas04.fyi/img/blog/prahlad-1.jpg" alt="Prahlad in lap of his angry father"></a></p>
<p>If you are to believe the ancient epic of Bhagat Prahlad and Hirnaykashyap, AKA Harnaakash in Sikhi, you'll find some interesting things around patriarchal family dynamics. There was an ideological difference between Prahlad and his father. His father felt superior and he felt that he was worthy of worship. This inflated self-view was further exemplified by the fact that his province &amp; society agreed, thanks to his boon of invincibility.</p>
<p><a class="blog-image-link" href="https://bogas04.fyi/img/blog/prahlad-2.jpg" target="_blank" rel="noopener noreferrer"><img src="https://bogas04.fyi/img/blog/prahlad-2.jpg" alt="Bhagat Prahlad in pyre chanting Ram Ram while his father watches him burn"></a></p>
<p>Prahlad, on other hand, by grace of his own wisdom given by Narad, believed Vishnu to be his God. This was completely unacceptable to his narcissist father. Prahlad's defiance was followed by series of attempts by his father to get his son to conform to his ideology.</p>
<p><a class="blog-image-link" href="https://bogas04.fyi/img/blog/prahlad-3.jpg" target="_blank" rel="noopener noreferrer"><img src="https://bogas04.fyi/img/blog/prahlad-3.jpg" alt="Narad giving spiritual wisdom to Prahlad's pregnant mother"></a></p>
<p>While the world around Hirnaykashyap believed him to be equivalent of God, Prahlad didn't bow down to his teachers, friends, sister and as well as his mother. He stood against and outright fought the entire world for his right to lead his life his way.</p>
<p><a class="blog-image-link" href="https://bogas04.fyi/img/blog/prahlad-4.jpg" target="_blank" rel="noopener noreferrer"><img src="https://bogas04.fyi/img/blog/prahlad-4.jpg" alt="Prahlad thrown off cliff only to be protected by Vishnu"></a></p>
<p>Imagine what a typical patriarchal mindset person in that era would have said. Wouldn't they instruct Prahald to leave his ego and just bow down to his parents? After all, his mother nurtured and nourished him, and his father took care of him, isn't it his moral obligation?</p>
<p><a class="blog-image-link" href="https://bogas04.fyi/img/blog/prahlad-5.jpg" target="_blank" rel="noopener noreferrer"><img src="https://bogas04.fyi/img/blog/prahlad-5.jpg" alt="Prahlad preaching his friends about Vishnu"></a></p>
<p>Guru Amardaas Jee, 3rd Guru of Sikhs, in his <a href="http://sttm.co/s/4054/48255">rendition</a> of the epic, shows how Prahlad talks back to his own mother.</p>
<p><a class="blog-image-link" href="https://bogas04.fyi/img/blog/prahlad-6.jpg" target="_blank" rel="noopener noreferrer"><img src="https://bogas04.fyi/img/blog/prahlad-6.jpg" alt="Shabad in Guru Granth Sahib showing how Bhagat Prahlad defies his mother"></a></p>
<p>Ultimately, after multiple attempts of coercing Prahlad, including multiple attempts of murder for not agreeing with his father, Prahlad was protected by Narsingh (an avatar of Vishnu) after He killed his father, thanks to some loop-hole in the invincibility spell.</p>
<p><a class="blog-image-link" href="https://bogas04.fyi/img/blog/prahlad-7.jpg" target="_blank" rel="noopener noreferrer"><img src="https://bogas04.fyi/img/blog/prahlad-7.jpg" alt="Narsingh killing Hirnaykashyap"></a></p>
<p>My point over here is that, since bygones we know of narcissism &amp; toxic patriarchy, and this story shows how a minor stood up against something he believed to be false and didn't bow down at all. In the world of obedient <a href="https://en.wikipedia.org/wiki/Shravan">Shravan Kumar</a> &amp; Raam, we also have disobedient Prahald.</p>
<p><a class="blog-image-link" href="https://bogas04.fyi/img/blog/prahlad-8.jpg" target="_blank" rel="noopener noreferrer"><img src="https://bogas04.fyi/img/blog/prahlad-8.jpg" alt="Shravan Kumar carrying his disabled parents"></a></p>
<p>Whether you believe children should indeed never defy their parents, or that Prahlad was an exception because he was a devotee of Vishnu, truth is that Prahlad wasn't supported by anyone he could rely on (his parents, siblings, friends or school) but he didn't conform to them.</p>
<p>In my opinion, the notion that children must be obedient to their parents is rejected by this story. Whether Prahlad was right or wrong, that's a separate ideological question, but we all can agree that children have been defying parents since bygones &amp; Sikhi even celebrates that.</p>
<p>The number of times Prahlad's story is mentioned in Sikhi, makes me feel that Gurus didn't really want Sikhs to become obedient children of their parents, but rather be autonomous and sovereign. Defiance against old systems is pretty much a norm in Sikhi.</p>
<p>Controlling parents and <a href="https://www.psychologytoday.com/us/blog/insight-is-2020/201405/narcissistic-parents-psychological-effect-their-children">emotional abuse by narcissistic parents</a> is not a new story, and it even needed intervention by Vishnu themself to save Prahlad.</p>
<p>If <a href="https://www.psychologytoday.com/us/blog/the-legacy-distorted-love/201802/the-real-effect-narcissistic-parenting-children">you're a victim</a> of such emotional abuse by controlling parents, you may take inspiration from this epic.</p>
]]></content:encoded>
</item>

<item>
<title><![CDATA[Effective Remote Communication]]></title>
<link>https://bogas04.fyi/blog/2020/11/effective-remote-communication</link>
<guid>https://bogas04.fyi/blog/2020/11/effective-remote-communication</guid>
<pubDate>Sun, 01 Nov 2020 06:02:13 GMT</pubDate>
<description><![CDATA[My take on team communication in a remote world.]]></description>
<content:encoded><![CDATA[<p>Thanks to COVID-19, working classes are either privileged to work remotely for their company, or severely unfortunate to lose their jobs and having to rebuild their careers from scratch. While the privilege of remote work is certainly a godsend, most companies, in my honest opinion, are struggling to make it work effectively. Here are some of my thoughts on how to improve that. I might be wrong or missing some points, would be more than happy to discuss about it on <a href="https://twitter.com/bogas04">Twitter</a>!</p>
<h2 id="asynchronous-communication"><a class="heading-permalink" href="https://bogas04.fyi/blog/2020/11/effective-remote-communication#asynchronous-communication" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text">Asynchronous Communication</span></a></h2>
<p>Pretty much all developers know how synchronous blocking code isn't really ideal, especially when multiple actors are involved. The same applies to a team of employees. If every problem requires another employee to stop what they're doing and help you out, it causes a pipeline stall. Because they've stalled what they were doing, dependents of their work would also be stalled. It isn't immediately obvious, but as the team scales without adopting asynchronous communication, productivity counter-intuitively decreases, despite the increase of workforce. In my opinion addition of new members doesn't also mean improvement of efficient communication amongst them.</p>
<p><a class="blog-image-link" href="https://bogas04.fyi/img/blog/asynchronous-vs-synchronous.png" target="_blank" rel="noopener noreferrer"><img src="https://bogas04.fyi/img/blog/asynchronous-vs-synchronous.png" alt="Image comparing how synchronously processes stall the pipeline while asynchronous processes do not do so"></a></p>
<ul>
<li>Make it easy for other person to reply quickly, for example:</li>
<li>
<ul>
<li>A yes/no question can be answered faster than an ambiguous monologue.</li>
</ul>
</li>
<li>
<ul>
<li>Scheduling a meeting in advance (after checking their calendar) is better than asking "are you free?" and waiting for hours.</li>
</ul>
</li>
<li>
<ul>
<li>Sharing relevant details/attachments is better than waiting for them to ask you for that.</li>
</ul>
</li>
<li>Sharing a deadline in your ask gives other person time to organize their week plans better.</li>
<li>Expect delays in replies, that's the norm, not an exception.</li>
<li>Keep some extra chores at hand while you wait for a reply, so as to not stay blocked until you receive one.</li>
</ul>
<h2 id="clear-articulate-communication"><a class="heading-permalink" href="https://bogas04.fyi/blog/2020/11/effective-remote-communication#clear-articulate-communication" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text">Clear Articulate Communication</span></a></h2>
<blockquote>
<p>Effective written communication becomes critical the more companies embrace remote work. With an aversion to "jumping on calls" at a whim, and a preference for asynchronous communication, most of remote-friendly company's communications are text-based, and so articulate and timely articulation becomes key.</p>
</blockquote>
<p><a href="https://medium.com/swlh/the-five-levels-of-remote-work-and-why-youre-probably-at-level-2-ccaf05a25b9c">Source</a></p>
<p><a class="blog-image-link" href="https://bogas04.fyi/img/blog/articulate-communication.png" target="_blank" rel="noopener noreferrer"><img src="https://bogas04.fyi/img/blog/articulate-communication.png" alt="Image comparing 3 examples of articulation. First: call the person directly to get answer, Second: &quot;a-fairly-large-module isn't working , can you join this meeting for 5 minutes?&quot;, Third: &quot;Hey, I got complete-error-message error when running code-snippet. I've tried attempts-to-fix and saw links-to-documentation, but I'm still stuck. Here's my code branch if you want to checkout and debug.&quot;></a>"></a></p><a class="blog-image-link" href="https://bogas04.fyi/img/blog/articulate-communication.png" target="_blank" rel="noopener noreferrer">
</a><p><a class="blog-image-link" href="https://bogas04.fyi/img/blog/articulate-communication.png" target="_blank" rel="noopener noreferrer">The next problem is that folks prefer to communicate as little as possible about their issue, while expect an immediate fix for their issue. Observe the three scenarios above. The first message is essentially a </a><a href="https://chelseatroy.com/2018/04/17/but-what-if-i-cannot-tap-my-remote-employee-on-the-shoulder/">shoulder tap equivalent of office</a>. You completely break the flow of the other person, without being considerate about their time and their context switch. Please don't do this unless it's basically EMERGENT as well as URGENT. To understand the difference between the two, let's look at this quote:</p>
<blockquote>
<p>The main difference between emergency and urgency is that in emergency there is immediate threat to life, health, property or environment; whereas in urgency, there is no immediate danger or threat to life, health, property or environment but if not taken care in a given period of time, then the situation may turn into an emergency situation.</p>
</blockquote>
<p><a href="http://www.differencebetween.net/science/nature/difference-between-urgence-and-emergency/">Source</a></p>
<p>I hope we can all agree that first message should ONLY be reserved for emergencies. If we keep crying foul, like calling a person to help with an unreleased software or upcoming demo, what eventually happens is that employees lose seriousness and start skipping calls. This can be catastrophic when you really have an emergency, like a huge outage or critical crash that's costing millions of dollars.</p>
<p>Now that we've established that the first message is basically reserved for emergencies, let's see why the second message isn't ideal either. The problem is that it's focused only in getting the solution, but with minimum effort. It's basically like asking someone to take over and fix your issue, i.e. <a href="https://theleegroup.com/spoon-fed-vs-supportive-management/">spoon feeding</a>. This is detrimental in several ways;</p>
<ul>
<li>You don't actually go through the process of reading, debugging, trying, thinking, and learn less.</li>
<li>You stop someone else from doing their work and making it difficult for them to resume after having disconnected the call.</li>
<li>The person who you're asking help from has to ask you a bunch of questions which you could've written to avoid extra time spent on the problem. "Did you try this? Did you read this? Can you share the error message? Can you share your branch?", all this could've been avoided and saved everybody's time.</li>
<li>It negatively effects the mood of the other person because deep down everyone wants to help each other, but they've to make a choice between being polite and slacking off in their job. That's a tough one and not everyone would be assertive enough to triage help.</li>
<li>Chances are, by the time you read the error message, Google a bit, read documentation and try certain fixes, you might have found the fix.</li>
</ul>
<p>Even if you are using the third message format, take some time to type out the entire thing, and re-read it yourself once. Not only you'll avoid spamming, you'll also get an opportunity for some self-reflection. Sometimes you just need to see a gist of the whole thing for something to "click".</p>
<h3 id="open-communication"><a class="heading-permalink" href="https://bogas04.fyi/blog/2020/11/effective-remote-communication#open-communication" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text">Open Communication</span></a></h3>
<p>Now that we understand importance of asynchronous and clear articulate communication, last thing that we need is open communication. There's no need to discuss in small silos when you know there are several of employees who might be facing the same issue, might have fixed it somehow and might have better ideas than the person you're taking help from. So asking for helping to your favorite goto person for xyz type of issue is only going to wear them out and give you less imaginative solutions. Discuss in open as much as possible, albeit in a clear articulate fashion, so as to enable meaningful discussion for systematic solutions.</p>
<ul>
<li>Try to discuss in channels &amp; groups, not just DMs.</li>
<li>Realize that asking questions in open doesn't reflect poorly on you.</li>
<li>Fear of conflicting opinions is a <a href="https://www.entrepreneur.com/article/238993">net negative for a team</a>.</li>
<li>Sharing your progress timely with the concerned audience helps in avoiding working in isolation.</li>
<li>Gathering continuous feedback from multiple people helps in adapting to changing requirements.</li>
</ul>
<p>I hope this post made some sense to you and encourages you to form <a href="https://www.careercontessa.com/advice/healthy-boundaries-at-work/">boundaries</a> for your sanity and that of your team members. I'll highly recommend you to go through the links I've shared in this blog to learn more.</p>
]]></content:encoded>
</item>

<item>
<title><![CDATA[JavaScript cheat sheet in 2020]]></title>
<link>https://bogas04.fyi/blog/2020/09/javascript-cheat-sheet-in-2020</link>
<guid>https://bogas04.fyi/blog/2020/09/javascript-cheat-sheet-in-2020</guid>
<pubDate>Mon, 14 Sep 2020 06:02:13 GMT</pubDate>
<description><![CDATA[List of snippets to learn basics of JavaScript]]></description>
<content:encoded><![CDATA[<p><a class="blog-image-link" href="https://bogas04.fyi/img/blog/ecmascript.png" target="_blank" rel="noopener noreferrer"><img src="https://bogas04.fyi/img/blog/ecmascript.png" alt="Evolution of ECMAScript"></a>
<a href="https://engineering.carsguide.com.au/javascript-context-ecmascript-84d709ef9165">Source</a></p>
<h2 id="basic-javascript-syntax"><a class="heading-permalink" href="https://bogas04.fyi/blog/2020/09/javascript-cheat-sheet-in-2020#basic-javascript-syntax" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text">Basic JavaScript syntax</span></a></h2>
<p>If you want to learn from a book, this is a great one <a href="https://exploringjs.com/impatient-js/toc.html">https://exploringjs.com/impatient-js/toc.html</a></p>
<h3 id="variable-definition"><a class="heading-permalink" href="https://bogas04.fyi/blog/2020/09/javascript-cheat-sheet-in-2020#variable-definition" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text"><strong>Variable definition</strong></span></a></h3>
<div><pre><code><span>const</span> a <span>=</span> <span>123</span><span>;</span>

<span>let</span> b <span>=</span> <span>123</span><span>;</span>
b <span>=</span> a<span>;</span>

<span>var</span> c <span>=</span> <span>123</span><span>;</span>
c <span>=</span> a<span>;</span>
</code></pre></div>
<h3 id="function-definition"><a class="heading-permalink" href="https://bogas04.fyi/blog/2020/09/javascript-cheat-sheet-in-2020#function-definition" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text"><strong>Function definition</strong></span></a></h3>
<div><pre><code><span>// function definition</span>
<span>function</span> <span>myFunction</span><span>(</span><span>)</span> <span>{</span><span>}</span>

<span>// function as a variable</span>
<span>const</span> <span>myFunction</span> <span>=</span> <span>function</span> <span>myFunction</span><span>(</span><span>)</span> <span>{</span><span>}</span><span>;</span>

<span>// anonymous function</span>
<span>const</span> <span>myFunction</span> <span>=</span> <span>function</span> <span>(</span><span>)</span> <span>{</span><span>}</span><span>;</span>

<span>// arrow function</span>
<span>const</span> <span>myFunction</span> <span>=</span> <span>(</span><span>)</span> <span>=&gt;</span> <span>{</span><span>}</span><span>;</span>
</code></pre></div>
<h3 id="strings"><a class="heading-permalink" href="https://bogas04.fyi/blog/2020/09/javascript-cheat-sheet-in-2020#strings" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text"><strong>Strings</strong></span></a></h3>
<div><pre><code><span>const</span> a <span>=</span> <span>"Hello, world"</span><span>;</span>

a<span>.</span><span>length</span><span>;</span> <span>// 12</span>

a<span>.</span><span>slice</span><span>(</span><span>3</span><span>,</span> <span>-</span><span>3</span><span>)</span><span>;</span> <span>// "lo, wo"</span>

a<span>.</span><span>split</span><span>(</span><span>","</span><span>)</span><span>;</span> <span>// ["Hello", " world]</span>

a<span>.</span><span>charAt</span><span>(</span><span>0</span><span>)</span><span>;</span> <span>// "H"</span>

a<span>[</span><span>0</span><span>]</span><span>;</span> <span>// "H"</span>

a<span>.</span><span>replace</span><span>(</span><span>"world"</span><span>,</span> <span>"you!"</span><span>)</span><span>;</span> <span>// "Hello, you!"</span>

a<span>.</span><span>slice</span><span>(</span><span>6</span><span>)</span><span>.</span><span>trim</span><span>(</span><span>)</span><span>;</span> <span>// " world" trims into "world"</span>

<span>const</span> b <span>=</span> a <span>+</span> <span>". Sup?"</span><span>;</span> <span>// "Hello, world. Sup?" (single quotes are also accepted)</span>

<span>const</span> c <span>=</span> <span><span>`</span><span><span>${</span>b<span>}</span></span><span>`</span></span><span>;</span> <span>// Template strings can interpolate variables</span>
</code></pre></div>
<h3 id="arrays"><a class="heading-permalink" href="https://bogas04.fyi/blog/2020/09/javascript-cheat-sheet-in-2020#arrays" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text"><strong>Arrays</strong></span></a></h3>
<div><pre><code><span>const</span> a <span>=</span> <span>[</span><span>"Hello,"</span><span>,</span> <span>"world"</span><span>]</span>

a<span>.</span><span>length</span> <span>// 2</span>

a<span>.</span><span>join</span><span>(</span><span>" "</span><span>)</span><span>;</span> <span>// "Hello, world"</span>

a<span>[</span><span>0</span><span>]</span> <span>// "Hello,"</span>

a<span>[</span>a<span>.</span><span>length</span> <span>-</span><span>1</span><span>]</span> <span>// "world"</span>

a<span>.</span><span>concat</span><span>(</span><span>"!"</span><span>)</span> <span>// ["Hello,", "world", "!"]</span>

a<span>.</span><span>find</span><span>(</span>e ⇒ e <span>===</span> <span>"!"</span><span>)</span> <span>// "!"</span>

a<span>.</span><span>find</span><span>(</span>e ⇒ e <span>===</span> <span>"definitely not in array"</span><span>)</span> <span>// undefined</span>

a<span>.</span><span>indexOf</span><span>(</span><span>"world"</span><span>)</span> <span>// 1</span>

a<span>.</span><span>push</span><span>(</span><span>"Sup?"</span><span>)</span> <span>// returns new length of mutated array ["Hello,", "world", "!", "Sup?"]</span>

a<span>.</span><span>pop</span><span>(</span><span>)</span> <span>// removes last item</span>

b<span>.</span><span>shift</span><span>(</span><span>)</span> <span>// removes  first item, shifts left, ["world", "!"]</span>

b<span>.</span><span>unshift</span><span>(</span><span>"Hello!"</span><span>)</span> <span>// puts new item to beginning ["Hello!", "world", "!"]</span>

<span>// destructuring</span>
<span>const</span> <span>[</span>first<span>,</span> second<span>]</span> <span>=</span> <span>[</span><span>"Hello"</span><span>,</span> <span>"world"</span><span>]</span> <span>// first is Hello", second is "world"</span>
<span>const</span> <span>[</span>first<span>,</span> <span>...</span>rest<span>]</span> <span>=</span> <span>[</span><span>1</span><span>,</span> <span>2</span><span>,</span> <span>3</span><span>,</span> <span>4</span><span>]</span> <span>// first is 1, rest is [2, 3, 4]</span>

<span>// spreading</span>
<span>const</span> c <span>=</span> <span>[</span>first<span>,</span> <span>...</span>rest<span>]</span> <span>// c is [1, 2, 3, 4]</span>

</code></pre></div>
<h3 id="objects"><a class="heading-permalink" href="https://bogas04.fyi/blog/2020/09/javascript-cheat-sheet-in-2020#objects" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text"><strong>Objects</strong></span></a></h3>
<p>JSON is first class citizen. The quotes around key aren't necessary.</p>
<div><pre><code><span>const</span> o <span>=</span> <span>{</span>

  <span>name</span><span>:</span> <span>"Human"</span><span>,</span>

  <span>age</span><span>:</span> <span>200000</span><span>,</span>

  <span>greet</span> <span>(</span><span>)</span> <span>{</span>
    <span>console</span><span>.</span><span>log</span><span>(</span><span><span>`</span><span>Hi! I'm </span><span><span>${</span><span>this</span><span>.</span><span>name</span><span>}</span></span><span> and I'm </span><span><span>${</span><span>this</span><span>.</span><span>age</span><span>}</span></span><span> years old</span><span>`</span></span><span>)</span><span>;</span>
  <span>}</span>

<span>}</span>

o<span>.</span><span>greet</span><span>(</span><span>)</span><span>;</span> <span>// prints "Hi! I'm Human and I'm 200000 years old"</span>
<span>[</span>o<span>.</span><span>name</span><span>]</span><span>(</span>http<span>:</span><span>/</span><span>/</span>o<span>.</span><span>name</span><span>)</span> <span>// "Human"</span>

o<span>[</span><span>'age'</span><span>]</span> <span>// 200000</span>

<span>const</span> key <span>=</span> condition <span>?</span> <span>"name"</span> <span>:</span> <span>"age"</span><span>;</span>

o<span>[</span>key<span>]</span> <span>// depending on condition it'll be "Human" or 200000</span>

o<span>.</span><span>newKey</span> <span>=</span> <span>[</span><span>1</span><span>,</span><span>2</span><span>,</span><span>3</span><span>]</span><span>;</span> <span>// o now has name, age and newKey</span>

<span>Object</span><span>.</span><span>keys</span><span>(</span>o<span>)</span> <span>// ["name", "age", "newKey"]</span>

<span>Object</span><span>.</span><span>entries</span><span>(</span>o<span>)</span> <span>// [["name", "Human"], ["age", 200000], ["newKey", [1,2,3]]</span>

<span>// destructuring</span>

<span>const</span> <span>{</span>name<span>}</span> <span>=</span> o<span>;</span> <span>// name is Human</span>
<span>const</span> <span>{</span>
  greet<span>,</span>
  <span>...</span>restOfObject
<span>}</span> <span>=</span> o<span>;</span> <span>// greet is function, restOfObject is {name: "Human", age: 200000}</span>

<span>// spreading</span>
<span>const</span> myNewPerson <span>=</span> <span>{</span>
  <span>...</span>restOfObject<span>,</span>
  <span>greet</span> <span>(</span><span>)</span> <span>{</span>
    <span>console</span><span>.</span><span>log</span><span>(</span><span><span>`</span><span>Yo! This is </span><span><span>${</span><span>this</span><span>.</span><span>name</span><span>}</span></span><span> over here. Imma </span><span><span>${</span><span>this</span><span>.</span><span>age</span><span>}</span></span><span> year old!</span><span>`</span></span><span>)</span><span>;</span>
  <span>}</span>
<span>}</span>

<span>// property shorthands</span>

<span>const</span> myName <span>=</span> <span>"is khan"</span><span>;</span>

<span>const</span> object <span>=</span> <span>{</span> myName <span>}</span> <span>// same as { myName: myName }</span>
</code></pre></div>
<h3 id="conditional-constructs"><a class="heading-permalink" href="https://bogas04.fyi/blog/2020/09/javascript-cheat-sheet-in-2020#conditional-constructs" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text"><strong>Conditional Constructs</strong></span></a></h3>
<div><pre><code><span>if</span> <span>(</span>condition<span>)</span> <span>{</span>
  <span>a</span><span>(</span><span>)</span><span>;</span>
<span>}</span> <span>else</span> <span>if</span> <span>(</span>condition2<span>)</span> <span>{</span>
  <span>b</span><span>(</span><span>)</span><span>;</span>
<span>}</span> <span>else</span> <span>{</span>
  <span>c</span><span>(</span><span>)</span><span>;</span>
<span>}</span>

condition <span>?</span> <span>a</span><span>(</span><span>)</span> <span>:</span> condition2 <span>?</span> <span>b</span><span>(</span><span>)</span> <span>:</span> <span>c</span><span>(</span><span>)</span><span>;</span>

condition <span>&amp;&amp;</span> <span>a</span><span>(</span><span>)</span><span>;</span> <span>// iff condition is truth-y, a would be executed</span>

<span>a</span><span>(</span><span>)</span> <span>||</span> <span>b</span><span>(</span><span>)</span><span>;</span> <span>// if result of a() is truth-y, b won't be executed</span>
</code></pre></div>
<h3 id="looping-constructs"><a class="heading-permalink" href="https://bogas04.fyi/blog/2020/09/javascript-cheat-sheet-in-2020#looping-constructs" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text"><strong>Looping Constructs</strong></span></a></h3>
<div><pre><code><span>// for loop</span>
<span>for</span> <span>(</span><span>let</span> i <span>=</span> <span>0</span><span>;</span> i <span>&lt;</span> arr<span>.</span><span>length</span><span>;</span> i<span>++</span><span>)</span> <span>{</span><span>}</span>

<span>//while loo</span>
<span>let</span> i <span>=</span> <span>0</span><span>;</span>

<span>while</span> <span>(</span>i <span>&lt;</span> arr<span>.</span><span>length</span><span>)</span> <span>{</span>
  i<span>++</span><span>;</span>
<span>}</span>

<span>// do-while</span>
<span>let</span> i <span>=</span> <span>0</span><span>;</span>

<span>do</span> <span>{</span>
  i<span>++</span><span>;</span>
<span>}</span> <span>while</span> <span>(</span>i <span>&lt;</span> arr<span>.</span><span>length</span><span>)</span><span>;</span>

<span>// for-in loop to loop through keys of an object</span>

<span>for</span> <span>(</span><span>let</span> key <span>in</span> object<span>)</span> <span>{</span>
<span>}</span>

<span>// for-of loop to loop through values of an array</span>

<span>for</span> <span>(</span><span>let</span> value <span>of</span> array<span>)</span> <span>{</span>
<span>}</span>
</code></pre></div>
<h3 id="functional"><a class="heading-permalink" href="https://bogas04.fyi/blog/2020/09/javascript-cheat-sheet-in-2020#functional" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text"><strong>Functional</strong></span></a></h3>
<div><pre><code><span>// loops through all items of arr array</span>
arr<span>.</span><span>forEach</span><span>(</span><span>(</span><span>index<span>,</span> value<span>,</span> array</span><span>)</span> <span>=&gt;</span> <span>{</span><span>}</span><span>)</span><span>;</span>

<span>// loops through all items of arr array and returns modified array</span>
arr<span>.</span><span>map</span><span>(</span><span>(</span><span>index<span>,</span> value<span>,</span> array</span><span>)</span> <span>=&gt;</span> modifiedItem<span>)</span><span>;</span>

<span>// returns array with items where cond(value) is true</span>
arr<span>.</span><span>filter</span><span>(</span><span>(</span><span>index<span>,</span> value<span>,</span> array</span><span>)</span> <span>=&gt;</span> <span>cond</span><span>(</span>value<span>)</span><span>)</span><span>;</span>

<span>// returns true if any item has cond(value) true</span>
arr<span>.</span><span>some</span><span>(</span><span>(</span><span>index<span>,</span> value<span>,</span> array</span><span>)</span> <span>=&gt;</span> <span>cond</span><span>(</span>value<span>)</span><span>)</span><span>;</span>

<span>// returns true if all items have cond(value) true</span>
arr<span>.</span><span>every</span><span>(</span><span>(</span><span>index<span>,</span> value<span>,</span> array</span><span>)</span> <span>=&gt;</span> <span>cond</span><span>(</span>value<span>)</span><span>)</span><span>;</span>

<span>// returns undefined or first item matching cond(value)</span>
arr<span>.</span><span>find</span><span>(</span><span>(</span><span>index<span>,</span> value<span>,</span> array</span><span>)</span> <span>=&gt;</span> <span>cond</span><span>(</span>value<span>)</span><span>)</span><span>;</span>
</code></pre></div>
<h3 id="classes"><a class="heading-permalink" href="https://bogas04.fyi/blog/2020/09/javascript-cheat-sheet-in-2020#classes" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text"><strong>Classes</strong></span></a></h3>
<div><pre><code><span>class</span> <span>A</span> <span>{</span>
  <span>constructor</span><span>(</span><span>name</span><span>)</span> <span>{</span>
    <span>this</span><span>.</span><span>name</span> <span>=</span> name<span>;</span>
  <span>}</span>
  <span>static</span> variable <span>=</span> <span>123</span><span>;</span>
  <span>static</span> <span>utilityMethod</span><span>(</span><span>)</span> <span>{</span><span>}</span>
  <span>method</span><span>(</span><span>)</span> <span>{</span><span>}</span>
<span>}</span>

<span>const</span> a <span>=</span> <span>new</span> <span>A</span><span>(</span><span>"Human"</span><span>)</span><span>;</span>

a<span>.</span><span>method</span><span>(</span><span>)</span><span>;</span>

<span>A</span><span>.</span><span>utilityMethod</span><span>(</span><span>)</span><span>;</span>

<span>A</span><span>.</span><span>variable</span><span>;</span>

<span>// Shorthand for instance variables</span>
<span>class</span> <span>B</span> <span>{</span>
  counter <span>=</span> <span>0</span><span>;</span>
  <span>increment</span> <span>=</span> <span>(</span><span>)</span> <span>=&gt;</span> <span>{</span>
    <span>this</span><span>.</span><span>counter</span> <span>+=</span> <span>1</span><span>;</span>
    <span>return</span> <span>this</span><span>.</span><span>counter</span><span>;</span>
  <span>}</span><span>;</span>
<span>}</span>
<span>// same as</span>
<span>class</span> <span>B</span> <span>{</span>
  <span>constructor</span><span>(</span><span>)</span> <span>{</span>
    <span>this</span><span>.</span><span>counter</span> <span>=</span> <span>0</span><span>;</span>
    <span>this</span><span>.</span><span>increment</span> <span>=</span> <span>(</span><span>)</span> <span>=&gt;</span> <span>{</span>
      <span>this</span><span>.</span><span>counter</span> <span>+=</span> <span>1</span><span>;</span>
      <span>return</span> <span>this</span><span>.</span><span>counter</span><span>;</span>
    <span>}</span><span>;</span>
  <span>}</span>
<span>}</span>

<span>// Difference between defining instance method and class method (class A#method)</span>
<span>// is that instance methods are created for each instance</span>
<span>// while class method reference is reused between all instances</span>
<span>// so if you're dealing with a lot of instances of same class</span>
<span>// method will be better memory-wise</span>
</code></pre></div>
<h3 id="asynchronous-code"><a class="heading-permalink" href="https://bogas04.fyi/blog/2020/09/javascript-cheat-sheet-in-2020#asynchronous-code" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text"><strong>Asynchronous code</strong></span></a></h3>
<div><pre><code><span>// Callbacks</span>
<span>function</span> <span>executeAfterOneSecond</span> <span>(</span><span>fn</span><span>)</span> <span>{</span>
  <span>setTimeout</span><span>(</span><span>(</span><span>)</span> <span>=&gt;</span> <span>{</span>
    <span>fn</span><span>(</span><span>)</span><span>;</span>
  <span>}</span><span>,</span> <span>1000</span><span>)</span><span>;</span>
<span>}</span>

<span>executeAfterOneSecond</span><span>(</span><span>(</span><span>)</span> <span>=&gt;</span> <span>console</span><span>.</span><span>log</span><span>(</span><span>"b"</span><span>)</span><span>)</span><span>;</span>
<span>console</span><span>.</span><span>log</span><span>(</span><span>"a"</span><span>)</span><span>;</span>

<span>// unlike blocking languages, setTimeout won't block execution</span>
<span>// we'll see "a" and "b" after a second, even if we've b being executed before</span>

<span>// Learn more about event loop: https://www.youtube.com/watch?v=8aGhZQkoFbQ</span>

<span>// In this example we saw setTimeout accepting a function and so did executeAfterOneSecond</span>
<span>// This makes it a higher order function, and fn is called a callback</span>
<span>// as in, once you're done, call [me] back.</span>

<span>// Promises</span>
<span>// Imagine everything being executed via callbacks</span>
<span>callApi</span><span>(</span>apiUrl<span>,</span> <span>(</span><span>result</span><span>)</span> <span>=&gt;</span> <span>{</span>
  <span>convertToJson</span><span>(</span>result<span>,</span> <span>(</span><span>json</span><span>)</span> <span>=&gt;</span> <span>{</span>
	<span>transformData</span><span>(</span>json<span>,</span> <span>(</span><span>data</span><span>)</span> <span>=&gt;</span> <span>{</span>
		<span>callAnotherApi</span><span>(</span>apiUrl2<span>,</span> data<span>,</span> <span>(</span><span>finalResult</span><span>)</span> <span>=&gt;</span> <span>{</span>
			<span>notifyUser</span><span>(</span>finalResult<span>)</span><span>;</span>
		<span>}</span><span>)</span><span>;</span>
        <span>}</span><span>)</span><span>;</span>
  <span>}</span><span>)</span><span>;</span>
<span>}</span><span>)</span><span>;</span>

<span>// While this is good as our code doesn't block any user action like scrolling</span>
<span>// it's hard to read and is usually referred to as "Callback hell"</span>

<span>// Promises were designed to make this pyramid shape more flat</span>

<span>// A promise is an instance of class Promise that has two main methods then &amp; catch</span>

<span>const</span> <span>callApi</span> <span>=</span> <span>apiUrl</span> <span>=&gt;</span> <span>new</span> <span>Promise</span><span>(</span><span>(</span><span>resolve<span>,</span> reject</span><span>)</span> <span>=&gt;</span> <span>{</span>
  <span>lowLevelFunctionToCallNetwork</span><span>(</span>apiUrl<span>,</span> <span>(</span><span>err<span>,</span> data</span><span>)</span> <span>=&gt;</span> <span>{</span>
    <span>if</span> <span>(</span>err<span>)</span> <span>reject</span><span>(</span>err<span>)</span><span>;</span>
    <span>else</span> <span>resolve</span><span>(</span>data<span>)</span><span>;</span>
  <span>}</span><span>)</span>
<span>}</span><span>)</span><span>;</span>

<span>callApi</span><span>(</span>apiUrl<span>)</span>
  <span>.</span><span>then</span><span>(</span>convertToJson<span>)</span>
  <span>.</span><span>then</span><span>(</span>transformData<span>)</span>
  <span>.</span><span>then</span><span>(</span><span>(</span><span>data</span><span>)</span> <span>=&gt;</span> <span>callAnotheApi</span><span>(</span>apiUrl2<span>,</span> data<span>)</span><span>)</span>
  <span>.</span><span>then</span><span>(</span>notifyUser<span>)</span><span>;</span>

<span>// Async/await makes it even more easier</span>

<span>async</span> <span>function</span> <span>(</span><span>)</span> <span>{</span>
  <span>const</span> result <span>=</span> <span>await</span> <span>callApi</span><span>(</span>apiUrl<span>)</span><span>;</span>
  <span>const</span> json <span>=</span> <span>await</span> <span>transformData</span><span>(</span>result<span>)</span><span>;</span>
  <span>const</span> finalResult <span>=</span>  <span>callAnotherApi</span><span>(</span>apiUrl2<span>,</span> data<span>)</span><span>;</span>
  <span>notifyUser</span><span>(</span>finalResult<span>)</span><span>;</span>
<span>}</span><span>(</span><span>)</span><span>;</span>
</code></pre></div>
<h3 id="module-system"><a class="heading-permalink" href="https://bogas04.fyi/blog/2020/09/javascript-cheat-sheet-in-2020#module-system" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text"><strong>Module system</strong></span></a></h3>
<p>In my opinion, frontend code grows much faster than backend code. Not only you deal with calling various APIs and data transformation techniques, you also bind all that to UI, while taking care of navigation, animations, performance, accessibility and so on.</p>
<p>Without the ability of converting code snippets into tiny reusable modules, you'll end up in a great spaghetti code with business logic, API logic, performance optimizations, UI, animations etc. all in one file.</p>
<p>Let's first cover imports</p>
<div><pre><code><span>// assuming "react" is in package.json's dependencies</span>
<span>// present in &lt;root&gt;/node_modules</span>

<span>// imports only the the default export.</span>
<span>import</span> <span><span>React</span></span> <span>from</span> <span>"react"</span><span>;</span>
<span>// imports all the named and default export as React.</span>
<span>import</span> <span><span>*</span> <span>as</span> <span>React</span></span> <span>from</span> <span>"react"</span><span>;</span>

<span>// you can change the name as you find fit</span>
<span>// note: in case of React you really need to name it React for JSX transpilation</span>
<span>import</span> <span><span>ICanChangeTheNameToAnything</span></span> <span>from</span> <span>"react"</span><span>;</span>

<span>// you can destructure from modules</span>
<span>import</span> <span><span>{</span> <span>Component</span><span>,</span> useState<span>,</span> useEffect <span>}</span></span> <span>from</span> <span>"react"</span><span>;</span>

<span>// you can rename a destructured value from a module using `as` keyword.</span>
<span>import</span> <span><span>{</span> <span>Component</span> <span>as</span> <span>ReactComponent</span> <span>}</span></span> <span>from</span> <span>"react"</span><span>;</span>

<span>// for local imports, you need to give relative path (in context of current file)</span>
<span>import</span> <span><span>*</span> <span>as</span> mypackage</span> <span>from</span> <span>"./my-package"</span><span>;</span>

<span>// All import paths have to be statically known, so you can't put a variable in there.</span>
</code></pre></div>
<p>Now that we know how to import, let's focus on exports</p>
<div><pre><code><span>export</span> <span>const</span> a <span>=</span> <span>1</span><span>;</span> <span>// imported as import {a} from './my-package';</span>

<span>export</span> <span>function</span> <span>print</span><span>(</span><span><span>...</span>args</span><span>)</span> <span>{</span>
  <span>// imported as import {print} from "./my-package";</span>
  <span>console</span><span>.</span><span>log</span><span>(</span><span>...</span>args<span>)</span><span>;</span>
<span>}</span>

<span>const</span> b <span>=</span> <span>2</span><span>;</span>
<span>const</span> c <span>=</span> <span>3</span><span>;</span>
<span>const</span> d <span>=</span> <span>4</span><span>;</span>

<span>export</span> <span><span>{</span> b<span>,</span> c<span>,</span> d <span>}</span></span><span>;</span> <span>// imported as import { b, c, d } from "./my-package";</span>

<span>export</span> <span>default</span> a<span>;</span> <span>// imported as import a from "./my-package";</span>

<span>export</span> <span><span>*</span></span> <span>from</span> <span>"./some-other-package"</span><span>;</span> <span>// exports evertyhing in some-other-package</span>
</code></pre></div>
]]></content:encoded>
</item>

<item>
<title><![CDATA[Learning ReactJS in 2020]]></title>
<link>https://bogas04.fyi/blog/2020/09/learning-reactjs-in-2020</link>
<guid>https://bogas04.fyi/blog/2020/09/learning-reactjs-in-2020</guid>
<pubDate>Mon, 14 Sep 2020 06:02:13 GMT</pubDate>
<description><![CDATA[My take on introducing you to ReactJS]]></description>
<content:encoded><![CDATA[<p><strong>Prerequisites</strong>: Working knowledge of JavaScript, ES6 features (classes, arrow functions at least). Here's a <a href="https://bogas04.fyi/blog/javascript-cheat-sheet-in-2020-9-14-2020">cheatsheet</a> for same.</p>
<p><a class="blog-image-link" href="https://bogas04.fyi/img/blog/reactjs.png" target="_blank" rel="noopener noreferrer"><img src="https://bogas04.fyi/img/blog/reactjs.png" alt="ReactJS Logo"></a>
Screenshot of official <a href="https://reactjs.org">ReactJS</a> website.</p>
<h2 id="why-do-we-even-need-react"><a class="heading-permalink" href="https://bogas04.fyi/blog/2020/09/learning-reactjs-in-2020#why-do-we-even-need-react" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text">Why do we even need React?</span></a></h2>
<ul>
<li>Every frontend application deals with calling APIs, transforming data, listening to user's actions (click, key presses) and updating UI accordingly.</li>
<li>As you have more and more interactable/dynamic elements in your UI, keeping a reference of each element and manually changing it whenever data (let's call it state of application) changes can be cumbersome. It can also be hard to remember to update all elements that are related to one particular state variable.</li>
<li>Let's take example of an app like Swiggy. When I click on add item, see how many elements update, and how many calculations are going on.</li>
</ul>
<p></p>
<ul>
<li>Not just that, there are a lot of edge cases that have to be handled. Observe what happens when I try to add item from other restaurant.</li>
</ul>
<p></p>
<ul>
<li>Clearly manually updating each state variable and element is invitation to a messy codebase. And we've not yet seen how hard it can be to update UI code.</li>
<li>For something as simple as updating text of any element, we've to do the following. Imagine having id's all over your HTML code and writing code to manually mutate every single field, each time one state variable changes.</li>
</ul>
<div><pre><code><span>// pseudo-ish code, just to illustrate how one might tackle the problem</span>
<span>// with imperative procedural approach</span>

<span>const</span> addToCart <span>=</span> <span>document</span><span>.</span><span>getElementById</span><span>(</span><span>"add-to-cart"</span><span>)</span><span>;</span>

addToCart<span>.</span><span>addEventListener</span><span>(</span><span>"click"</span><span>,</span> <span>(</span><span>e</span><span>)</span> <span>=&gt;</span> <span>{</span>
  <span>if</span> <span>(</span><span>getCartRestaurant</span><span>(</span><span>)</span> <span>!==</span> <span>getCurrentRestaurant</span><span>(</span><span>)</span><span>)</span> <span>{</span>
    <span>showPopup</span><span>(</span><span>)</span><span>;</span>
    <span>return</span><span>;</span>
  <span>}</span>

  e<span>.</span><span>target</span><span>.</span><span>innerText</span> <span>=</span> e<span>.</span><span>target</span><span>.</span><span>innerText</span> <span>+</span> <span>1</span><span>;</span>

  <span>const</span> itemDetails <span>=</span> itemStore<span>.</span><span>get</span><span>(</span>addToCart<span>.</span><span>data</span><span>.</span><span>itemId</span><span>)</span><span>;</span>
  <span>if</span> <span>(</span><span>!</span><span>cartExists</span><span>(</span><span>)</span><span>)</span> <span>{</span>
    <span>addCartToUI</span><span>(</span><span>)</span><span>;</span> <span>// series of commands to build up cart UI</span>
    <span>addItemToCartUI</span><span>(</span>itemDetails<span>)</span><span>;</span> <span>// series of commands to update cart UI with new itemDetails</span>
  <span>}</span>

  <span>addItemToCartUI</span><span>(</span>itemDetails<span>)</span><span>;</span>
<span>}</span><span>)</span><span>;</span>
</code></pre></div>
<ul>
<li>This is where React comes handy by abstracting the imperative commands in a declarative API, while also making it reactive to state changes. So whenever our state changes, React will take care of updating the UI as defined by our code.</li>
</ul>
<div><pre><code><span><span><span>&lt;</span>button</span> <span>onClick</span><span><span>=</span><span>{</span><span>(</span><span>)</span> <span>=&gt;</span> <span>addItemToCartState</span><span>(</span>itemDetails<span>)</span><span>}</span></span><span>&gt;</span></span><span>Add</span><span><span><span>&lt;/</span>button</span><span>&gt;</span></span><span>;</span>
<span>{</span>
  cartExists <span>&amp;&amp;</span> <span><span><span>&lt;</span><span>Cart</span></span> <span>items</span><span><span>=</span><span>{</span>cart<span>.</span><span>items</span><span>}</span></span> <span>/&gt;</span></span><span>;</span>
<span>}</span>
<span>{</span>
  cartExists <span>&amp;&amp;</span> currentRestaurant <span>!==</span> cart<span>.</span><span>restaurant</span> <span>&amp;&amp;</span> <span><span><span>&lt;</span><span>Popup</span></span> <span>/&gt;</span></span><span>;</span>
<span>}</span>
</code></pre></div>
<ul>
<li>React takes care of rendering to UI, we just need to make update cart state, the components would react to it naturally. By making reusable components like Cart and Popup, you don't have to duplicate code each time you want to construct UI and behavior around it. Components can naturally compose making it really easy to write code.</li>
<li>React Native is another platform that uses React in its core. All fundamentals of React are ditto same in React Native, with only differences in some APIs and core components provided. The value proposition of React Native is that unlike native apps, you can use single codebase for iOS, Android and Web, while also bypassing App store/Play store for releasing non-native changes (all UI &amp; business logic majorly). We'll discuss this point later.</li>
</ul>
<h2 id="jsx---the-language-of-react"><a class="heading-permalink" href="https://bogas04.fyi/blog/2020/09/learning-reactjs-in-2020#jsx---the-language-of-react" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text">JSX - The language of React</span></a></h2>
<div><pre><code><span>import</span> <span><span>React</span></span> <span>from</span> <span>"react"</span><span>;</span>

<span>function</span> <span><span>Person</span></span><span>(</span><span>props</span><span>)</span> <span>{</span>
  <span>return</span> <span>(</span>
    <span><span><span>&lt;</span>div</span><span>&gt;</span></span><span></span>
<span>      </span><span><span><span>&lt;</span>h1</span> <span>style</span><span><span>=</span><span>{</span><span>{</span> <span>color</span><span>:</span> <span>"red"</span> <span>}</span><span>}</span></span><span>&gt;</span></span><span>{</span>props<span>.</span><span>name</span><span>}</span><span><span><span>&lt;/</span>h1</span><span>&gt;</span></span><span></span>
<span>    </span><span><span><span>&lt;/</span>div</span><span>&gt;</span></span>
  <span>)</span><span>;</span>
<span>}</span>

<span>// is transpiled into</span>

<span>import</span> <span><span>React</span></span> <span>from</span> <span>"react"</span><span>;</span>

<span>function</span> <span><span>Person</span></span><span>(</span><span>props</span><span>)</span> <span>{</span>
  <span>return</span> <span>React</span><span>.</span><span>createElement</span><span>(</span>
    <span>"div"</span><span>,</span>
    <span>null</span><span>,</span>
    <span>React</span><span>.</span><span>createElement</span><span>(</span><span>"h1"</span><span>,</span> <span>{</span> <span>style</span><span>:</span> <span>{</span> <span>color</span><span>:</span> <span>"red"</span> <span>}</span> <span>}</span><span>,</span> props<span>.</span><span>name</span><span>)</span>
  <span>)</span><span>;</span>
<span>}</span>
</code></pre></div>
<p>Before we understand React, we must first take time to understand JSX, the way you describe UI in React Applications. JSX is basically an extension to JavaScript to add support for XML like syntax. While JSX isn't necessary, it does make it much more easy to write code. React's philosophy deviates from traditional template based frameworks (Angular, Vue, Svelte) in the sense that it doesn't mix programming constructs into the template, but rather mixes HTML into JavaScript itself.</p>
<p>This makes writing UI code familiar to HTML, while also having access to entire JavaScript syntax. This IMO reduces a lot of boilerplate and template specific knowledge.</p>
<p>Note: A tool like babel or typescript can be used to do this transformation. Note, as it is JSX won't run on browser, it needs to be converted to JavaScript, hence the need of a build tool.</p>
<div><pre><code><span><span><span>&lt;</span><span>MyComponent</span></span> <span>isActive</span> <span>/&gt;</span></span><span>;</span>
<span>// is transpiled into</span>
<span>React</span><span>.</span><span>createElement</span><span>(</span><span>MyComponent</span><span>,</span> <span>{</span> isActive<span>:</span> <span>true</span> <span>}</span><span>)</span><span>;</span>

<span><span><span>&lt;</span><span>MyComponent</span></span> <span>isActive</span> <span><span>{</span><span>...</span>props<span>}</span></span> <span>/&gt;</span></span><span>;</span>
<span>// is loosely transpiled into</span>
<span>React</span><span>.</span><span>createElement</span><span>(</span><span>MyComponent</span><span>,</span> <span>{</span> isActive<span>:</span> <span>true</span><span>,</span> <span>...</span>props <span>}</span><span>)</span><span>;</span>
</code></pre></div>
<h2 id="a-react-component"><a class="heading-permalink" href="https://bogas04.fyi/blog/2020/09/learning-reactjs-in-2020#a-react-component" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text">A React component</span></a></h2>
<p>Now that we know how to express UI in a React app efficiently (code readability wise), we can look into an actual React component now.</p>
<p>There are 3 primary parts to a React component. It can have internal state, it can listen to props sent by its parent component, and it can return a sub-tree of UI expressed as JSX.</p>
<p>There are two paradigms you can follow to make a React Component.</p>
<ul>
<li>
<p>Class based components</p>
<blockquote>
<p>Any class that extends either of <code>React.Component</code> and implements at a bare minimum render method that returns JSX, is a class based component.</p>
</blockquote>
</li>
</ul>
<div><pre><code><span>// basic example</span>
<span>class</span> <span>MyComponent</span> <span>extends</span> <span>React<span>.</span>Component</span> <span>{</span>
  <span>render</span><span>(</span><span>)</span> <span>{</span>
    <span>return</span> <span><span><span>&lt;</span>h1</span><span>&gt;</span></span><span>Hello!</span><span><span><span>&lt;/</span>h1</span><span>&gt;</span></span><span>;</span>
  <span>}</span>
<span>}</span>
</code></pre></div>
<ul>
<li>
<p>Functional components</p>
<blockquote>
<p>Any function that returns JSX is a functional component.</p>
</blockquote>
</li>
</ul>
<div><pre><code><span>// basic example</span>
<span>function</span> <span><span>MyComponent</span></span><span>(</span><span>)</span> <span>{</span>
  <span>return</span> <span><span><span>&lt;</span>h1</span><span>&gt;</span></span><span>Hello!</span><span><span><span>&lt;/</span>h1</span><span>&gt;</span></span><span>;</span>
<span>}</span>

<span>// smoller plz</span>
<span>const</span> <span><span>MyComponent</span></span> <span>=</span> <span>(</span><span>)</span> <span>=&gt;</span> <span>{</span>
  <span>return</span> <span><span><span>&lt;</span>h1</span><span>&gt;</span></span><span>Hello!</span><span><span><span>&lt;/</span>h1</span><span>&gt;</span></span><span>;</span>
<span>}</span><span>;</span>

<span>// i sed smolllllll</span>
<span>const</span> <span><span>MyComponent</span></span> <span>=</span> <span>(</span><span>)</span> <span>=&gt;</span> <span><span><span>&lt;</span>h1</span><span>&gt;</span></span><span>Hello!</span><span><span><span>&lt;/</span>h1</span><span>&gt;</span></span><span>;</span>
</code></pre></div>
<p>As you can see, functional component seem to be quite simple in their definition. Each component can accept props and can have an internal state. But how do these access props and state?</p>
<h3 id="props"><a class="heading-permalink" href="https://bogas04.fyi/blog/2020/09/learning-reactjs-in-2020#props" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text">Props</span></a></h3>
<div><pre><code><span>// functional component</span>
<span>function</span> <span><span>MyComponent</span></span><span>(</span><span>props</span><span>)</span> <span>{</span>
  <span>return</span> <span><span><span>&lt;</span>h1</span><span>&gt;</span></span><span>{</span>props<span>.</span><span>title</span><span>}</span><span><span><span>&lt;/</span>h1</span><span>&gt;</span></span><span>;</span>
<span>}</span>

<span>// class based component</span>
<span>class</span> <span>MyComponent</span> <span>extends</span> <span>React<span>.</span>Component</span> <span>{</span>
  <span>render</span><span>(</span><span>)</span> <span>{</span>
    <span>return</span> <span><span><span>&lt;</span>h1</span><span>&gt;</span></span><span>{</span><span>this</span><span>.</span><span>props</span><span>.</span><span>title</span><span>}</span><span><span><span>&lt;/</span>h1</span><span>&gt;</span></span><span>;</span>
  <span>}</span>
<span>}</span>
</code></pre></div>
<h3 id="state"><a class="heading-permalink" href="https://bogas04.fyi/blog/2020/09/learning-reactjs-in-2020#state" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text">State</span></a></h3>
<div><pre><code><span>// functional component</span>
<span>function</span> <span><span>MyComponent</span></span><span>(</span><span>)</span> <span>{</span>
  <span>const</span> <span>[</span>count<span>,</span> setCount<span>]</span> <span>=</span> <span>useState</span><span>(</span><span>0</span><span>)</span><span>;</span>
  <span>return</span> <span><span><span>&lt;</span>button</span> <span>onClick</span><span><span>=</span><span>{</span><span>(</span><span>)</span> <span>=&gt;</span> <span>setCount</span><span>(</span>count <span>+</span> <span>1</span><span>)</span><span>}</span></span><span>&gt;</span></span><span>{</span>count<span>}</span><span><span><span>&lt;/</span>button</span><span>&gt;</span></span><span>;</span>
<span>}</span>

<span>// class based component</span>
<span>class</span> <span>MyComponent</span> <span>extends</span> <span>React<span>.</span>Component</span> <span>{</span>
  <span>constructor</span><span>(</span><span>props</span><span>)</span> <span>{</span>
    <span>super</span><span>(</span>props<span>)</span><span>;</span>
    <span>this</span><span>.</span><span>state</span> <span>=</span> <span>{</span> <span>count</span><span>:</span> <span>0</span> <span>}</span><span>;</span>
  <span>}</span>
  <span>render</span><span>(</span><span>)</span> <span>{</span>
    <span>return</span> <span>(</span>
      <span><span><span>&lt;</span>button</span> <span>onClick</span><span><span>=</span><span>{</span><span>(</span><span>)</span> <span>=&gt;</span> <span>this</span><span>.</span><span>setState</span><span>(</span><span>{</span> <span>count</span><span>:</span> <span>this</span><span>.</span><span>state</span><span>.</span><span>count</span> <span>+</span> <span>1</span> <span>}</span><span>)</span><span>}</span></span><span>&gt;</span></span><span></span>
<span>        </span><span>{</span>count<span>}</span><span></span>
<span>      </span><span><span><span>&lt;/</span>button</span><span>&gt;</span></span>
    <span>)</span><span>;</span>
  <span>}</span>
<span>}</span>

<span>// smoller plz</span>
<span>class</span> <span>MyComponent</span> <span>extends</span> <span>React<span>.</span>Component</span> <span>{</span>
  state <span>=</span> <span>{</span> <span>count</span><span>:</span> <span>0</span> <span>}</span><span>;</span>
  <span>render</span><span>(</span><span>)</span> <span>{</span>
    <span>return</span> <span>(</span>
      <span><span><span>&lt;</span>button</span> <span>onClick</span><span><span>=</span><span>{</span><span>(</span><span>)</span> <span>=&gt;</span> <span>this</span><span>.</span><span>setState</span><span>(</span><span>{</span> <span>count</span><span>:</span> <span>this</span><span>.</span><span>state</span><span>.</span><span>count</span> <span>+</span> <span>1</span> <span>}</span><span>)</span><span>}</span></span><span>&gt;</span></span><span></span>
<span>        </span><span>{</span>count<span>}</span><span></span>
<span>      </span><span><span><span>&lt;/</span>button</span><span>&gt;</span></span>
    <span>)</span><span>;</span>
  <span>}</span>
<span>}</span>
</code></pre></div>
<p>There's fundamental difference in idea of state in a class component and functional component. In a class component, entire state is part of <code>this.state</code> and each state variable would be a key of it. While in functional component, each state variable is created individually by virtue of <code>useState</code>, a magical-looking function that somehow remembers current state value between renders, and can differentiate one from another. You can also see how state is tightly coupled to the class (it's directly inside the constructor), while in case of function, it is yet another function call. If say you had 3 state variables, you can group 3 <code>useState</code>s in one function call and use it. This isn't quite intuitively obvious when we see class based components.</p>
<p>Originally, we only had class based components as the only viable option as only they supported state and other features. However, React introduced concept of <a href="http://reactjs.org/hooks">hooks</a> (such as <code>useState</code>), that gives a lot of flexibility to functional components making them not only on-par but actually superior in terms of code re-usability and agility.</p>
<p>Since it's much simpler to understand functional components, we'll go through them first so that you can contribute ASAP. When we discuss lifecycle methods, we'll learn more about the differences.</p>
<h3 id="lifecycles-and-side-effects"><a class="heading-permalink" href="https://bogas04.fyi/blog/2020/09/learning-reactjs-in-2020#lifecycles-and-side-effects" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text">Lifecycles and Side-effects</span></a></h3>
<p>Having access to state and props is very powerful to create dynamic UIs. However, you also need to know about the lifecycle of a component. You may want to call an API as soon as the UI is visible to user. Or may want to cancel a polling request as soon as the component is removed from current tree of components. You may want to know when a <code>query</code> prop has been updated by a parent of a <code>&lt;Search query={userQuery} /&gt;</code> component, to fetch new results based on updated <code>query</code>. All these are side effects of component's life cycle. Perform this side effect when some event occurs (component loads, state changes, prop changes, component unloads to name a few).</p>
<p>Let's see how to listen to these events in class based components first.</p>
<h3 id="class-based-components"><a class="heading-permalink" href="https://bogas04.fyi/blog/2020/09/learning-reactjs-in-2020#class-based-components" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text">Class Based Components</span></a></h3>
<h4 id="when-a-component-loads"><a class="heading-permalink" href="https://bogas04.fyi/blog/2020/09/learning-reactjs-in-2020#when-a-component-loads" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text">When a component loads</span></a></h4>
<div><pre><code><span>class</span> <span>MyComponent</span> <span>extends</span> <span>React<span>.</span>Component</span> <span>{</span>
  state <span>=</span> <span>{</span> <span>loading</span><span>:</span> <span>true</span><span>,</span> <span>data</span><span>:</span> <span>null</span> <span>}</span><span>;</span>

  <span>async</span> <span>componentDidMount</span><span>(</span><span>)</span> <span>{</span>
    <span>// perform on load side effects</span>
    <span>const</span> data <span>=</span> <span>await</span> <span>callApi</span><span>(</span><span>)</span><span>;</span>
    <span>this</span><span>.</span><span>setState</span><span>(</span><span>{</span> data<span>,</span> <span>loading</span><span>:</span> <span>false</span> <span>}</span><span>)</span><span>;</span>
  <span>}</span>

  <span>render</span><span>(</span><span>)</span> <span>{</span>
    <span>const</span> <span>{</span> loading<span>,</span> data <span>}</span> <span>=</span> <span>this</span><span>.</span><span>state</span><span>;</span>
    <span>if</span> <span>(</span>loading<span>)</span> <span>return</span> <span>"Loading..."</span><span>;</span>

    <span>return</span> <span><span><span>&lt;</span><span>User</span></span> <span>data</span><span><span>=</span><span>{</span>data<span>.</span><span>user</span><span>}</span></span> <span>/&gt;</span></span><span>;</span>
  <span>}</span>
<span>}</span>
</code></pre></div>
<h4 id="when-a-component-is-removed-from-tree"><a class="heading-permalink" href="https://bogas04.fyi/blog/2020/09/learning-reactjs-in-2020#when-a-component-is-removed-from-tree" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text">When a component is removed from tree</span></a></h4>
<div><pre><code><span>class</span> <span>MyComponent</span> <span>extends</span> <span>React<span>.</span>Component</span> <span>{</span>
  state <span>=</span> <span>{</span> <span>timer</span><span>:</span> <span>0</span> <span>}</span><span>;</span>

  <span>// update state.timer every 1000 ms</span>
  <span>poll</span> <span>=</span> <span>(</span><span>)</span> <span>=&gt;</span>
    <span>setInterval</span><span>(</span>
      <span>(</span><span>)</span> <span>=&gt;</span> <span>this</span><span>.</span><span>setState</span><span>(</span><span>(</span><span>oldState</span><span>)</span> <span>=&gt;</span> <span>(</span><span>{</span> <span>timer</span><span>:</span> oldState<span>.</span><span>timer</span> <span>+</span> <span>1</span> <span>}</span><span>)</span><span>)</span><span>,</span>
      <span>1000</span>
    <span>)</span><span>;</span>

  <span>componentDidMount</span><span>(</span><span>)</span> <span>{</span>
    <span>this</span><span>.</span><span>timer</span> <span>=</span> <span>poll</span><span>(</span><span>)</span><span>;</span>
  <span>}</span>

  <span>componentWillUnmount</span><span>(</span><span>)</span> <span>{</span>
    <span>clearInterval</span><span>(</span><span>this</span><span>.</span><span>timer</span><span>)</span><span>;</span>
  <span>}</span>

  <span>render</span><span>(</span><span>)</span> <span>{</span>
    <span>return</span> <span><span><span>&lt;</span>h1</span><span>&gt;</span></span><span>{</span><span>this</span><span>.</span><span>state</span><span>.</span><span>timer</span><span>}</span><span><span><span>&lt;/</span>h1</span><span>&gt;</span></span><span>;</span>
  <span>}</span>
<span>}</span>
</code></pre></div>
<h4 id="when-a-prop-is-updated"><a class="heading-permalink" href="https://bogas04.fyi/blog/2020/09/learning-reactjs-in-2020#when-a-prop-is-updated" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text">When a prop is updated</span></a></h4>
<div><pre><code><span>class</span> <span>MyComponent</span> <span>extends</span> <span>React<span>.</span>Component</span> <span>{</span>
  state <span>=</span> <span>{</span><span>results</span><span>:</span> <span>[</span><span>]</span><span>,</span> <span>loading</span><span>:</span> <span>true</span><span>}</span>

  <span>componentDidMount</span><span>(</span><span>)</span> <span>{</span>
      <span>fetchNewResultsAndUpdateState</span><span>(</span><span>this</span><span>.</span><span>props</span><span>.</span><span>query</span><span>)</span><span>;</span>
  <span>}</span>
  <span>componentDidUpdate</span><span>(</span><span>prevProps<span>,</span> prevState</span><span>)</span> <span>{</span>
    <span>// query updated</span>
    <span>if</span> <span>(</span>prevProps<span>.</span><span>query</span> <span>!==</span> <span>this</span><span>.</span><span>props</span><span>.</span><span>query</span><span>)</span> <span>{</span>
      <span>fetchNewResultsAndUpdateState</span><span>(</span><span>this</span><span>.</span><span>props</span><span>.</span><span>query</span><span>)</span><span>;</span>
    <span>}</span>
  <span>}</span>
  <span>render</span><span>(</span><span>)</span> <span>{</span>
    <span>const</span> <span>{</span>results<span>,</span>loading<span>}</span> <span>=</span> <span>this</span><span>.</span><span>state</span><span>;</span>

    <span>if</span> <span>(</span>loading<span>)</span> <span>return</span> <span>"Getting your results..."</span><span>;</span>

    <span>return</span> <span>(</span>
      <span><span><span>&lt;</span></span><span>&gt;</span></span><span></span>
<span>        </span><span>{</span>results<span>.</span><span>map</span><span>(</span><span>result</span> <span>=&gt;</span> <span><span><span>&lt;</span><span>SearchResult</span></span> <span>result</span><span><span>=</span><span>{</span>result<span>}</span></span> <span>key</span><span><span>=</span><span>{</span>result<span>.</span><span>id</span><span>}</span></span> <span>/&gt;</span></span><span>)</span><span>}</span><span></span>
<span>      </span><span><span><span>&lt;/</span></span><span>&gt;</span></span><span>;</span>
    <span>)</span>

  <span>}</span>
  <span>async</span> <span>fetchNewResultsAndUpdateState</span> <span>=</span> <span>query</span> <span>=&gt;</span> <span>{</span>
     <span>this</span><span>.</span><span>setState</span><span>(</span><span>{</span><span>loading</span><span>:</span> <span>true</span><span>}</span><span>)</span><span>;</span>
     <span>const</span> results <span>=</span> <span>await</span> <span>getResults</span><span>(</span>query<span>)</span><span>;</span>
     <span>this</span><span>.</span><span>setState</span><span>(</span><span>{</span><span>loading</span><span>:</span> <span>false</span><span>,</span>results<span>}</span><span>)</span><span>;</span>
  <span>}</span>
<span>}</span>
</code></pre></div>
<p>There are several more lifecycle methods provided by React.Component, but I think these 3 are enough for you to build highly dynamic UIs that are memory safe. They're quite powerful and let you know achieve a lot of complex interactions.</p>
<p>However, remember I told how class based components are tightly coupled to the business logic and are hence quite verbose?</p>
<ul>
<li>Logic to call API whenever a component loads seems to be a generic problem, but due to the way React classes are designed, it's hard to abstract this out in a neat way. There are several advanced patterns like Render Props and Higher Order Functions to mitigate that. Each time you want to call an API on load of a component, you've to write this logic in one way or another.</li>
<li>Since we can define <code>componentDidMount</code>, <code>componentDidUpdate</code> and <code>componentWillUnmount</code> only once, they'll keep the logic to call APIs, unsubscribe from intervals and subscriptions, clean up other resources in a one huge block. We can't really abstract it out as they're all interdependent. In our timer example, we need to rely on <code>componentDidMount</code> to set <code>this.timer</code> so that we can clear it in <code>componentWillUnmount</code>.</li>
<li>The logic to check which prop has been updated can quickly become a mess if you've to listen to changes on multiple props. What we really want to do is "whenever props.query changes, do this" but what we're actually doing is "whenever component updates, check if it updated due to change in query, if that's the case, do this". Also, since <code>componentDidUpdate</code> isn't fired when component is loaded, we need to perform the call in <code>componentDidMount</code> as well.</li>
</ul>
<h3 id="functional-components"><a class="heading-permalink" href="https://bogas04.fyi/blog/2020/09/learning-reactjs-in-2020#functional-components" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text">Functional Components</span></a></h3>
<p>Now that we've seen the power of lifecycle methods, let's see how functional components achieve that with basically making use <code>useEffect</code>. As you can imagine, <code>useEffect</code> seems to be a hook doing a lot of heavy lifting, so let's spend some time understanding it before going through above use cases.</p>
<p>Let's first see the signature of <code>useEffect</code>.</p>
<div><pre><code><span>// a function returning nothing</span>
<span>type</span> <span>CleanupType</span> <span>=</span> <span>(</span><span>)</span> <span>=&gt;</span> <span>void</span><span>;</span>
<span>// a function returning a CleanupType function</span>
<span>type</span> <span>CallbackType</span> <span>=</span> <span>(</span><span>)</span> <span>=&gt;</span> <span>CleanupType</span><span>;</span>

<span>// accepts CallbackType function and Dependency array, returns nothing</span>
<span>type</span> <span>UseEffectType</span> <span>=</span> <span>(</span><span>CallbackType</span><span>,</span> <span>Dependency</span><span>[</span><span>]</span><span>)</span> <span>=&gt;</span> <span>void</span><span>;</span>

<span>// example</span>

<span>useEffect</span><span>(</span><span>(</span><span>)</span> <span>=&gt;</span> <span>{</span>
  <span>doSomething</span><span>(</span>a<span>)</span><span>;</span>
  <span>return</span> <span>(</span><span>)</span> <span>=&gt;</span> <span>doSomethingElse</span><span>(</span>a<span>)</span><span>;</span>
<span>,</span> <span>[</span>a<span>]</span><span>)</span><span>;</span>
</code></pre></div>
<p>In above example, we are basically asking react to <code>doSomething</code> whenever <code>a</code> changes (dependency list tells react to listen to changes on that variable). And whenever <code>a</code> transitions from one value to another, before considering the new value, call <code>doSomethingElse</code>. This can be seen as an opportunity to do cleanup. Clear polling functions, unsubscribing event listeners, saving some state to storage etc.</p>
<p>An empty dependency list would imply whenever the component that has invoked this hook mounted and unmounted. If you omit the dependency list altogether, then you're essentially telling React to run your code on each render. You almost never want this.</p>
<div><pre><code><span>function</span> <span>MyComponent</span><span>(</span><span>)</span> <span>{</span>
  <span>useEffect</span><span>(</span><span>(</span><span>)</span> <span>=&gt;</span> <span>{</span>
    <span>doSomething</span><span>(</span><span>)</span><span>;</span>
  <span>}</span><span>)</span><span>;</span>

  <span>// is loosely same as</span>
  <span>doSomething</span><span>(</span><span>)</span><span>;</span>
<span>}</span>
</code></pre></div>
<p>We can already see how the hooks aren't tied to the functional component that is invoking them, and that we can have multiple number of <code>useEffect</code>s, just like <code>useState</code>. Lastly, it's just a function call, and multiple such <code>useState</code> and <code>useEffect</code> s could be hidden beneath one <code>useComplexStuff</code> hook call.</p>
<p>Let's go through the use-cases mentioned above but using functional components now.</p>
<h4 id="when-a-component-loads-1"><a class="heading-permalink" href="https://bogas04.fyi/blog/2020/09/learning-reactjs-in-2020#when-a-component-loads-1" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text">When a component loads</span></a></h4>
<div><pre><code><span>function</span> <span><span>MyComponent</span></span><span>(</span><span>)</span> <span>{</span>
  <span>// unlike class components, each state variable is individually stored</span>
  <span>const</span> <span>[</span>loading<span>,</span> setLoading<span>]</span> <span>=</span> <span>useState</span><span>(</span><span>true</span><span>)</span><span>;</span>
  <span>const</span> <span>[</span>data<span>,</span> setData<span>]</span> <span>=</span> <span>useState</span><span>(</span><span>null</span><span>)</span><span>;</span>

  <span>useEffect</span><span>(</span><span>(</span><span>)</span> <span>=&gt;</span> <span>{</span>
    <span>callApi</span><span>(</span><span>)</span><span>.</span><span>then</span><span>(</span><span>(</span><span>data</span><span>)</span> <span>=&gt;</span> <span>{</span>
      <span>setData</span><span>(</span>data<span>)</span><span>;</span>
      <span>setLoading</span><span>(</span><span>false</span><span>)</span><span>;</span>
    <span>}</span><span>)</span><span>;</span>
  <span>}</span><span>,</span> <span>[</span><span>]</span><span>)</span><span>;</span>

  <span>if</span> <span>(</span>loading<span>)</span> <span>return</span> <span>"Loading..."</span><span>;</span>

  <span>return</span> <span><span><span>&lt;</span><span>User</span></span> <span>data</span><span><span>=</span><span>{</span>data<span>.</span><span>user</span><span>}</span></span> <span>/&gt;</span></span><span>;</span>
<span>}</span>
</code></pre></div>
<p>Please go through it and let me know if you've any questions. Try to absorb this API.</p>
<p>Now let's see if we can truly abstract out this logic to call API on component load.</p>
<div><pre><code><span>// so smoll. much nice.</span>
<span>function</span> <span>MyComponent</span><span>(</span><span>)</span> <span>{</span>
  <span>const</span> <span>[</span>loading<span>,</span> data<span>]</span> <span>=</span> <span>useUser</span><span>(</span><span>)</span><span>;</span>

  <span>if</span> <span>(</span>loading<span>)</span> <span>return</span> <span>"Loading..."</span><span>;</span>

  <span>return</span> <span><span><span>&lt;</span><span>User</span></span> <span>data</span><span><span>=</span><span>{</span>data<span>.</span><span>user</span><span>}</span></span> <span>/&gt;</span></span><span>;</span>
<span>}</span>

<span>// but how do we implement useUser?</span>
<span>function</span> <span>useUser</span><span>(</span><span>)</span> <span>{</span>
  <span>const</span> <span>[</span>loading<span>,</span> setLoading<span>]</span> <span>=</span> <span>useState</span><span>(</span><span>true</span><span>)</span><span>;</span>
  <span>const</span> <span>[</span>data<span>,</span> setData<span>]</span> <span>=</span> <span>useState</span><span>(</span><span>null</span><span>)</span><span>;</span>

  <span>useEffect</span><span>(</span><span>(</span><span>)</span> <span>=&gt;</span> <span>{</span>
    <span>callApi</span><span>(</span><span>)</span><span>.</span><span>then</span><span>(</span><span>(</span>data<span>)</span> <span>=&gt;</span> <span>{</span>
      <span>setData</span><span>(</span>data<span>)</span><span>;</span>
      <span>setLoading</span><span>(</span><span>false</span><span>)</span><span>;</span>
    <span>}</span><span>)</span><span>;</span>
  <span>}</span><span>,</span> <span>[</span><span>]</span><span>)</span><span>;</span>

  <span>// this is the only extra line i've added to previous code.</span>
  <span>// It's basically copy paste refactoring</span>
  <span>return</span> <span>[</span>loading<span>,</span> data<span>]</span><span>;</span>
<span>}</span>
</code></pre></div>
<h4 id="when-a-component-is-removed-from-tree-1"><a class="heading-permalink" href="https://bogas04.fyi/blog/2020/09/learning-reactjs-in-2020#when-a-component-is-removed-from-tree-1" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text">When a component is removed from tree</span></a></h4>
<p>Remember how I said <code>componentWillUnmount</code> depends on variables set by <code>componentDidMount</code>. Well, in case of <code>useEffect</code> the cleanup function has access to all variables created by the effect part of the function. So that's convenient.</p>
<div><pre><code><span>function</span> <span>MyComponent</span><span>(</span><span>)</span> <span>{</span>
  <span>const</span> <span>[</span>timer<span>,</span> setTimer<span>]</span> <span>=</span> <span>useState</span><span>(</span><span>0</span><span>)</span><span>;</span>

  <span>useEffect</span><span>(</span><span>(</span><span>)</span> <span>=&gt;</span> <span>{</span>
    <span>const</span> interval <span>=</span> <span>setInterval</span><span>(</span><span>(</span><span>)</span> <span>=&gt;</span> <span>setTimer</span><span>(</span><span>(</span>t<span>)</span> <span>=&gt;</span> t <span>+</span> <span>1</span><span>)</span><span>,</span> <span>1000</span><span>)</span><span>;</span>
    <span>return</span> <span>(</span><span>)</span> <span>=&gt;</span> <span>clearInterval</span><span>(</span>interval<span>)</span><span>;</span>
  <span>}</span><span>,</span> <span>[</span><span>]</span><span>)</span><span>;</span>

  <span>return</span> <span><span><span>&lt;</span>h1</span><span>&gt;</span></span><span>{</span>timer<span>}</span><span><span><span>&lt;/</span>h1</span><span>&gt;</span></span><span>;</span>
<span>}</span>
</code></pre></div>
<p>And again, we can abstract this into a <code>useInterval</code> hook. These custom hooks are called, yup, custom hooks. Prefix them with a <code>use</code> so that it plays nicely with <a href="https://www.npmjs.com/package/eslint-plugin-react-hooks">eslint-plugin-react-hooks</a>.</p>
<div><pre><code><span>function</span> <span>MyComponent</span><span>(</span><span>)</span> <span>{</span>
  <span>const</span> timer <span>=</span> <span>useTimer</span><span>(</span><span>0</span><span>)</span><span>;</span>

  <span>return</span> <span><span><span>&lt;</span>h1</span><span>&gt;</span></span><span>{</span>timer<span>}</span><span><span><span>&lt;/</span>h1</span><span>&gt;</span></span><span>;</span>
<span>}</span>

<span>function</span> <span>useTimer</span><span>(</span>defaultValue<span>)</span> <span>{</span>
  <span>const</span> <span>[</span>timer<span>,</span> setTimer<span>]</span> <span>=</span> <span>useState</span><span>(</span>defaultValue<span>)</span><span>;</span>

  <span>useEffect</span><span>(</span><span>(</span><span>)</span> <span>=&gt;</span> <span>{</span>
    <span>const</span> interval <span>=</span> <span>setInterval</span><span>(</span><span>(</span><span>)</span> <span>=&gt;</span> <span>setTimer</span><span>(</span><span>(</span>t<span>)</span> <span>=&gt;</span> t <span>+</span> <span>1</span><span>)</span><span>,</span> <span>1000</span><span>)</span><span>;</span>
    <span>return</span> <span>(</span><span>)</span> <span>=&gt;</span> <span>clearInterval</span><span>(</span>interval<span>)</span><span>;</span>
  <span>}</span><span>,</span> <span>[</span><span>]</span><span>)</span><span>;</span>

  <span>return</span> timer<span>;</span>
<span>}</span>
</code></pre></div>
<p>I hope you're now convinced that hooks are really powerful and highly composable. Let's see the final use case now.</p>
<h4 id="when-a-prop-is-updated-1"><a class="heading-permalink" href="https://bogas04.fyi/blog/2020/09/learning-reactjs-in-2020#when-a-prop-is-updated-1" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text">When a prop is updated</span></a></h4>
<div><pre><code><span>function</span> <span>MyComponent</span><span>(</span>props<span>)</span> <span>{</span>
  <span>const</span> <span>[</span>results<span>,</span> setResults<span>]</span> <span>=</span> <span>useState</span><span>(</span><span>[</span><span>]</span><span>)</span><span>;</span>
  <span>const</span> <span>[</span>loading<span>,</span> setLoading<span>]</span> <span>=</span> <span>useState</span><span>(</span><span>true</span><span>)</span><span>;</span>

  <span>useEffect</span><span>(</span><span>(</span><span>)</span> <span>=&gt;</span> <span>{</span>
    <span>setLoading</span><span>(</span><span>true</span><span>)</span><span>;</span>
    <span>getResults</span><span>(</span>props<span>.</span><span>query</span><span>)</span><span>.</span><span>then</span><span>(</span><span>(</span>results<span>)</span> <span>=&gt;</span> <span>{</span>
      <span>setResults</span><span>(</span>results<span>)</span><span>;</span>
      <span>setLoading</span><span>(</span><span>false</span><span>)</span><span>;</span>
    <span>}</span><span>)</span><span>;</span>
  <span>}</span><span>,</span> <span>[</span>props<span>.</span><span>query</span><span>]</span><span>)</span><span>;</span>

  <span>if</span> <span>(</span>loading<span>)</span> <span>return</span> <span>"Getting your results..."</span><span>;</span>

  <span>return</span> <span>(</span>
    <span><span><span>&lt;</span></span><span>&gt;</span></span><span></span>
<span>      </span><span>{</span>results<span>.</span><span>map</span><span>(</span><span>(</span>result<span>)</span> <span>=&gt;</span> <span>(</span>
        <span><span><span>&lt;</span><span>SearchResult</span></span> <span>result</span><span><span>=</span><span>{</span>result<span>}</span></span> <span>key</span><span><span>=</span><span>{</span>result<span>.</span><span>id</span><span>}</span></span> <span>/&gt;</span></span>
      <span>)</span><span>)</span><span>}</span><span></span>
<span>    </span><span><span><span>&lt;/</span></span><span>&gt;</span></span>
  <span>)</span><span>;</span>
<span>}</span>
</code></pre></div>
<p>You can see how just with one <code>useEffect</code> we can handle both mounting and updating stages. This makes our code less verbose and more declarative. Unlike class example, we're really asking react to get results whenever query updates.</p>
<p>You might have observed how I've not used <code>async/await</code> syntax within a <code>useEffect</code> yet. It's because the <code>CallbackType</code> isn't an <code>async</code> function and it's expecting a callback in return, not a promise. If you really want to use async await syntax, you should try doing this:</p>
<div><pre><code><span>useEffect</span><span>(</span><span>(</span><span>)</span> <span>=&gt;</span> <span>{</span>
  <span>const</span> <span>fetchResults</span> <span>=</span> <span>async</span> <span>(</span><span>)</span> <span>=&gt;</span> <span>{</span>
    <span>setLoading</span><span>(</span><span>true</span><span>)</span><span>;</span>
    <span>const</span> results <span>=</span> <span>await</span> <span>getResults</span><span>(</span>props<span>.</span><span>query</span><span>)</span><span>;</span>
    <span>setResults</span><span>(</span>results<span>)</span><span>;</span>
    <span>setLoading</span><span>(</span><span>false</span><span>)</span><span>;</span>
  <span>}</span><span>;</span>
  <span>fetchResults</span><span>(</span><span>)</span><span>;</span>
<span>}</span><span>,</span> <span>[</span>props<span>.</span><span>query</span><span>]</span><span>)</span><span>;</span>
</code></pre></div>
<p>Now that we've seen enough hooks code, I think it's time to go through the <em><a href="https://reactjs.org/docs/hooks-rules.html">Rules of Hooks</a>.</em> Yes, they seem to be magical, but there are some rules that we need to follow to ensure React doesn't end up minimizing into a point of singularity and breaking the universe as we know it.</p>
<ol>
<li>Hooks must be only called from a React Functional Component or a custom hook.
You can't use it in a normal business logic function, or a class based component.</li>
<li>Hooks must be at top level of wherever it's being called from.
Basically, you can't use a hook inside a condition or loop.</li>
</ol>
<p>Go through the <a href="https://reactjs.org/docs/hooks-rules.html#explanation">documentation</a> to understand more about this.</p>
<h3 id="styling"><a class="heading-permalink" href="https://bogas04.fyi/blog/2020/09/learning-reactjs-in-2020#styling" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text">Styling</span></a></h3>
<p>So far you might have this <code>style</code> prop used on various components with an object with style related values in it.</p>
<div><pre><code><span><span><span>&lt;</span>h1</span> <span>style</span><span><span>=</span><span>{</span><span>{</span> color<span>:</span> <span>"red"</span><span>,</span> backgroundColor<span>:</span> <span>"blue"</span><span>,</span> marginRight<span>:</span> <span>10</span> <span>}</span><span>}</span></span><span>&gt;</span></span><span><span><span>&lt;/</span>h1</span><span>&gt;</span></span>
</code></pre></div>
<p>These are actually CSS style <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Reference#Keyword_index">rules</a> that React accepts for base components. Rules that have a hyphen are camel cased. So <code>margin-right</code> becomes <code>marginRight</code>. Also, you can pass numbers wherever applicable, <code>px</code> unit would be taken for those. So <code>marginRight: 10</code> is same as <code>margin-right: 10px;</code></p>
<p><strong>Note:</strong> Unlike CSS you can't define <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-classes">pseudo classes</a> like <code>:hover</code> or <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-elements">pseudo elements</a> like <code>::after</code>. You can achieve that by defining a CSS class outside of React and using it as <code>className</code> or using CSS-in-JS libraries like <a href="https://styled-components.com/">styled-components</a>.</p>
<h2 id="react-native"><a class="heading-permalink" href="https://bogas04.fyi/blog/2020/09/learning-reactjs-in-2020#react-native" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text">React Native</span></a></h2>
<p>Now that we've covered most of the basic fundamentals of ReactJS, let's see how <a href="https://reactnative.dev/">React Native</a> is different. In all our above examples, we're actually using ReactJS along with <a href="https://reactjs.org/docs/react-dom.html">ReactDOM</a>. It's the driver that knows what to do when we write a heading like follows.</p>
<div><pre><code><span><span><span>&lt;</span>h1</span> <span>style</span><span><span>=</span><span>{</span><span>{</span> color<span>:</span> <span>"red"</span> <span>}</span><span>}</span></span><span>&gt;</span></span><span>Hello</span><span><span><span>&lt;/</span>h1</span><span>&gt;</span></span>
</code></pre></div>
<p>It converts the <code>h1</code> to respective HTML <a href="https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Introduction">DOM</a> element, and applies the styling to it. So we can see that ReactJS (class components, state, lifecycle, props, composability, hooks etc.) is actually host platform agnostic. It can run on any platform as long as you provide a driver for the same. On Native platforms, <a href="https://reactnative.dev/">react-native</a> does that. You can image that we can't use <code>h1</code> and the like on native as they don't understand HTML. Instead, we've things like <code>TextView</code> on Android and <code>UITextView</code> on iOS and so on for all native UI elements. The driver takes care of mapping a <code>&lt;View style={{backgroundColor: 'red'}}&gt;&lt;/View&gt;</code> into a <code>UIView</code> object with background property set as "red" for iOS, likewise for Android.</p>
<p><a class="blog-image-link" href="https://reactnative.dev/docs/assets/diagram_ios-android-views.svg" target="_blank" rel="noopener noreferrer"><img src="https://reactnative.dev/docs/assets/diagram_ios-android-views.svg" alt="https://reactnative.dev/docs/assets/diagram_ios-android-views.svg"></a></p>
<p>So apart from using components like <code>View</code> <code>Text</code> <code>TextInput</code> <code>Image</code> etc in place of <code>div</code> <code>span</code> <code>input</code> <code>img</code> (respectively), the fundamentals remain the same. There's one more difference however, and that is styling:</p>
<ul>
<li>Just like native platforms don't understand HTML, they don't understand CSS either. Authors of React Native made <a href="https://yogalayout.com/docs">Yoga</a> a <a href="https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Flexbox">flexbox</a> implementation along with a CSS rule subset to native styling translation layer for native platforms.</li>
<li>Another thing is that unlike HTML where you can basically create any sort of hierarchy of elements, even if it doesn't make sense, React Native is more strict. Strings are only accepted by <code>&lt;Text/&gt;</code> and you can't place strings inside a <code>&lt;View /&gt;</code>, similarly rules around text (color, fontSize etc) don't have any effect on a <code>&lt;View /&gt;</code>. You need to assign it to the <code>&lt;Text /&gt;</code> directly.</li>
<li>Also the API of <code>style</code> prop is slightly different. We'll cover it next.</li>
</ul>
<h3 id="react-native-styling"><a class="heading-permalink" href="https://bogas04.fyi/blog/2020/09/learning-reactjs-in-2020#react-native-styling" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text">React Native Styling</span></a></h3>
<p>Unlike <a href="https://reactjs.org/docs/react-dom.html">react-dom</a>, <code>style</code> prop is slightly different in the sense that it also accepts an array. It can also accept object created by <code>StyleSheet.create</code></p>
<div><pre><code><span>// react-dom</span>
<span><span><span>&lt;</span>div</span> <span>style</span><span><span>=</span><span>{</span><span>{</span>margin<span>:</span> <span>10</span><span>,</span> backgroundColor<span>:</span> <span>'red'</span><span>}</span><span>}</span></span> <span>/&gt;</span></span>

<span>// react-native</span>
<span><span><span>&lt;</span><span>View</span></span> <span>style</span><span><span>=</span><span>{</span><span>{</span>margin<span>:</span> <span>10</span><span>,</span> backgroundColor<span>:</span> <span>'red'</span><span>}</span><span>}</span></span> <span>/&gt;</span></span>
<span>// or</span>
<span><span><span>&lt;</span><span>View</span></span> <span>style</span><span><span>=</span><span>{</span><span>[</span><span>{</span>margin<span>:</span> <span>10</span><span>}</span><span>,</span> <span>{</span>backgroundColor<span>:</span> <span>'red'</span><span>}</span><span>]</span><span>}</span></span> <span>/&gt;</span></span>
<span>// or</span>
<span>const</span> styles <span>=</span> <span>StyleSheet</span><span>.</span><span>create</span><span>(</span><span>{</span>
  container<span>:</span> <span>{</span>margin<span>:</span> <span>10</span><span>,</span> backgroundColor<span>:</span> <span>'red'</span><span>}</span>
<span>}</span><span>)</span>
<span><span><span>&lt;</span><span>View</span></span> <span>style</span><span><span>=</span><span>{</span>styles<span>.</span><span>container</span><span>}</span></span> <span>/&gt;</span></span>
</code></pre></div>
<h3 id="react-native-web"><a class="heading-permalink" href="https://bogas04.fyi/blog/2020/09/learning-reactjs-in-2020#react-native-web" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text">React Native Web</span></a></h3>
<p>We've come full circle with <a href="https://necolas.github.io/react-native-web/docs/?path=/docs/overview-getting-started--page">React Native Web</a>, which is basically a component library that has same API as <code>react-native</code> but is implemented with <code>react-dom</code> in mind. A view in <code>react-native-web</code> is essentially a <code>&lt;div /&gt;</code> . This might seem futile, however the power is that you can now write your code in React Native, and use it on web using <code>react-native-web</code>.</p>
<h2 id="advanced-patterns"><a class="heading-permalink" href="https://bogas04.fyi/blog/2020/09/learning-reactjs-in-2020#advanced-patterns" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text">Advanced Patterns</span></a></h2>
<p>These are now not as important with advent of hooks, however it's still important once in a while in your daily job. You can ignore these for now and comeback later whenever you encounter one.</p>
<h3 id="higher-order-components"><a class="heading-permalink" href="https://bogas04.fyi/blog/2020/09/learning-reactjs-in-2020#higher-order-components" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text">Higher Order Components</span></a></h3>
<p>Just like Higher Order Functions can accept a function and return a new one, High Order Components are functions that accept a component and return a new one. This can be used as a way to decorate a particular component with extra behavior.</p>
<p>Suppose we want to show a loader if <code>loading</code> prop is true, but we don't want to write this code for all components. We can create a <code>withLoader</code> higher order component to solve this.</p>
<div><pre><code><span>function</span> <span>withLoader</span><span>(</span><span>Component</span><span>)</span> <span>{</span>
  <span>return</span> <span>function</span> <span>LoaderContainer</span><span>(</span>props<span>)</span> <span>{</span>
    <span>if</span> <span>(</span>props<span>.</span><span>loading</span><span>)</span> <span>return</span> <span><span><span>&lt;</span><span>Loader</span></span> <span>/&gt;</span></span><span>;</span>
    <span>return</span> <span><span><span>&lt;</span><span>Component</span></span> <span><span>{</span><span>...</span>props<span>}</span></span> <span>/&gt;</span></span><span>;</span>
  <span>}</span><span>;</span>
<span>}</span>
</code></pre></div>
<p>Now we can wrap our components with <code>withLoader</code> whenever we want to add this behavior.</p>
<div><pre><code><span>// UserPage.js</span>
<span>class</span> <span>UserPage</span> <span>extends</span> <span>React</span><span>.</span><span><span>Component</span></span> <span>{</span>
  <span>...</span>
<span>}</span>

<span>export</span> <span>default</span> <span>withLoader</span><span>(</span><span>UserPage</span><span>)</span><span>;</span>

<span>// Home.js</span>
<span>function</span> <span>Home</span> <span>(</span><span>)</span> <span>{</span>
  <span>const</span> <span>[</span>loading<span>,</span> data<span>]</span> <span>=</span> <span>useUser</span><span>(</span><span>)</span><span>;</span>

  <span>return</span> <span><span><span>&lt;</span><span>UserPage</span></span> <span>loading</span><span><span>=</span><span>{</span>loading<span>}</span></span> <span>data</span><span><span>=</span><span>{</span>data<span>}</span></span> <span>/&gt;</span></span><span>;</span>
<span>}</span>
</code></pre></div>
<p>Multiple such HOCs can be used to add behavior. <a href="https://react-redux.js.org/api/connect">react-redux</a> actually exposes one popular HOC <code>connect</code> that lets you connect to the <a href="https://redux.js.org/">redux</a> store.</p>
<p>There are some caveats though:</p>
<ul>
<li>Our React tree will now have a <code>LoaderContainer</code> above each component using this HOC.</li>
<li>We can't add this behavior dynamically or conditionally, at build time we make the choice either to wrap a component in an HOC or not.</li>
<li>Passing a <a href="https://reactjs.org/docs/refs-and-the-dom.html">ref</a> won't give us <a href="https://reactjs.org/docs/refs-and-the-dom.html">ref</a> of our <code>Component</code>, but rather of <code>LoaderContainer</code>. To mitigate this most developers usually manually connect a <code>innerRef</code> prop to the inner component.</li>
</ul>
<div><pre><code><span>function</span> <span>withLoader</span><span>(</span><span>Component</span><span>)</span> <span>{</span>
  <span>return</span> <span>function</span> <span>LoaderContainer</span><span>(</span><span>{</span> innerRef<span>,</span> <span>...</span>props <span>}</span><span>)</span> <span>{</span>
    <span>if</span> <span>(</span>props<span>.</span><span>loading</span><span>)</span> <span>return</span> <span><span><span>&lt;</span><span>Loader</span></span> <span>/&gt;</span></span><span>;</span>
    <span>return</span> <span><span><span>&lt;</span><span>Component</span></span> <span>ref</span><span><span>=</span><span>{</span>innerRef<span>}</span></span> <span><span>{</span><span>...</span>props<span>}</span></span> <span>/&gt;</span></span><span>;</span>
  <span>}</span><span>;</span>
<span>}</span>
</code></pre></div>
<ul>
<li>The static fields on the component won't be accessible from the enhanced component. Suppose <code>UserPage</code> has a <code>MODES</code> field so that you can choose which mode of <code>UserPage</code> you want to render. To mitigate this, you can <a href="https://reactjs.org/docs/higher-order-components.html#static-methods-must-be-copied-over">hoist</a> the <a href="https://github.com/mridgway/hoist-non-react-statics">non-react statics</a>.</li>
</ul>
<div><pre><code><span>// UserPage.js</span>
<span>class</span> <span>UserPage</span> <span>extends</span> <span>React</span><span>.</span><span><span>Component</span></span> <span>{</span>
  <span>...</span>
  <span>static</span> <span>MODES</span> <span>=</span> <span>{</span><span>LITE</span><span>:</span> <span>0</span><span>,</span> <span>NORMAL</span><span>:</span> <span>1</span><span>}</span><span>;</span>
<span>}</span>

<span>export</span> <span>default</span> <span>withLoader</span><span>(</span><span>UserPage</span><span>)</span><span>;</span>

<span>// Home.js</span>
<span>function</span> <span>Home</span> <span>(</span><span>)</span> <span>{</span>
  <span>const</span> <span>[</span>loading<span>,</span> data<span>]</span> <span>=</span> <span>useUser</span><span>(</span><span>)</span><span>;</span>

  <span>// ❌ Won't work as withLoader doesn't expose the MODES static field.</span>
  <span>return</span> <span><span><span>&lt;</span><span>UserPage</span></span> <span>mode</span><span><span>=</span><span>{</span><span>UserPage</span><span>.</span><span>MODES</span><span>.</span><span>LITE</span><span>}</span></span> <span>loading</span><span><span>=</span><span>{</span>loading<span>}</span></span> <span>data</span><span><span>=</span><span>{</span>data<span>}</span></span> <span>/&gt;</span></span><span>;</span>
<span>}</span>
</code></pre></div>
<h3 id="render-props"><a class="heading-permalink" href="https://bogas04.fyi/blog/2020/09/learning-reactjs-in-2020#render-props" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text">Render props</span></a></h3>
<p>While HOCs are highly powerful, they have a lot of caveats that Render Props attempt to solve. Render props are just a fancy name given to a pattern in which makes use of the fact that <code>children</code> field (or any prop for that matter) of a component can actually be a function. Using this, we can put behavior in our Render Prop accepting Component and use it like any other React Component. This is in a way inversion of control, where you decide what you want to render. For an example, let's modify the first class based example of loading data on component load. This helps us extract the behavior out of our initial example and lets us reuse that logic wherever we want.</p>
<div><pre><code><span>class</span> <span>UserDataFetcher</span> <span>extends</span> <span>React</span><span>.</span><span><span>Component</span></span> <span>{</span>
  state <span>=</span> <span>{</span>loading<span>:</span> <span>true</span><span>,</span> data<span>:</span> <span>null</span><span>}</span>

  <span>async</span> <span>componentDidMount</span> <span>(</span><span>)</span> <span>{</span>
    <span>const</span> data <span>=</span> <span>await</span> <span>callApi</span><span>(</span><span>)</span><span>;</span>
    <span>this</span><span>.</span><span>setState</span><span>(</span><span>{</span>data<span>,</span> loading<span>:</span> <span>false</span><span>}</span><span>)</span><span>;</span>
  <span>}</span>

  <span>render</span><span>(</span><span>)</span> <span>{</span>
    <span>const</span> <span>{</span>loading<span>,</span> data<span>}</span> <span>=</span> <span>this</span><span>.</span><span>state</span><span>;</span>
    <span>return</span> <span>this</span><span>.</span><span>props</span><span>.</span><span>children</span><span>(</span>loading<span>,</span> data<span>)</span><span>;</span>
  <span>}</span>
<span>}</span>

<span>function</span> <span>App</span> <span>(</span><span>)</span> <span>{</span>
  <span>return</span> <span><span><span>&lt;</span><span>UserDataFetcher</span></span><span>&gt;</span></span><span>{</span><span>(</span>loading<span>,</span> data<span>)</span> <span>=&gt;</span> <span>{</span>
    <span>return</span> <span><span><span>&lt;</span><span>UserPage</span></span> <span>loading</span><span><span>=</span><span>{</span>loading<span>}</span></span> <span>data</span><span><span>=</span><span>{</span>data<span>}</span></span> <span>/&gt;</span></span>
   <span>}</span><span>}</span><span><span><span>&lt;/</span><span>WithUserData</span></span><span>&gt;</span></span><span></span>
<span>}</span>
</code></pre></div>
<p>I guess you can see why this was so powerful in pre-hooks era.</p>
<h2 id="optimizations"><a class="heading-permalink" href="https://bogas04.fyi/blog/2020/09/learning-reactjs-in-2020#optimizations" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text">Optimizations</span></a></h2>
<p>While React's internal architecture ensures app performance stays top-notch, there are some optimizations we can use to reduce load on user's system by avoiding large re-renders. See, each time reference of state or props of a component changes, React would re-render the component. This is how we achieve reactivity. However, React by default will make no checks and assumptions to see if the update prop or state is actually same as before.</p>
<div><pre><code><span>function</span> <span>MyComponent</span><span>(</span><span>)</span> <span>{</span>
  <span>const</span> <span>[</span>count<span>,</span> setCount<span>]</span> <span>=</span> <span>useState</span><span>(</span><span>0</span><span>)</span><span>;</span>

  <span>return</span> <span>(</span>
    <span><span><span>&lt;</span></span><span>&gt;</span></span><span></span>
<span>      </span><span><span><span>&lt;</span>button</span> <span>onClick</span><span><span>=</span><span>{</span><span>(</span><span>)</span> <span>=&gt;</span> <span>setCount</span><span>(</span><span>(</span>c<span>)</span> <span>=&gt;</span> c <span>+</span> <span>1</span><span>)</span><span>}</span></span><span>&gt;</span></span><span>{</span>count<span>}</span><span><span><span>&lt;/</span>button</span><span>&gt;</span></span><span></span>
<span>      </span><span><span><span>&lt;</span><span>Library</span></span> <span>version</span><span><span>=</span><span>"</span>1<span>"</span></span> <span>/&gt;</span></span><span></span>
<span>    </span><span><span><span>&lt;/</span></span><span>&gt;</span></span>
  <span>)</span><span>;</span>
<span>}</span>

<span>const</span> <span>Library</span> <span>=</span> <span>(</span><span>{</span> version <span>}</span><span>)</span> <span>=&gt;</span> <span>{</span>
  <span>return</span> <span><span><span>&lt;</span>h1</span><span>&gt;</span></span><span>The library version is </span><span>{</span>version<span>}</span><span><span><span>&lt;/</span>h1</span><span>&gt;</span></span><span>;</span>
<span>}</span><span>;</span>
</code></pre></div>
<p>Whenever <code>count</code> state variable updates in <code>MyComponent</code>, <code>MyComponent</code> would re-render. And since it re-renders, it'll cause <code>Library</code> to re-render as well. React wouldn't check if version has actually changed or not. If you wish to avoid a re-render of <code>Library</code>, you can use <code>React.memo</code></p>
<h3 id="reactmemo"><a class="heading-permalink" href="https://bogas04.fyi/blog/2020/09/learning-reactjs-in-2020#reactmemo" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text">React.memo</span></a></h3>
<div><pre><code><span>function</span> <span>MyComponent</span><span>(</span><span>)</span> <span>{</span>
  <span>const</span> <span>[</span>count<span>,</span> setCount<span>]</span> <span>=</span> <span>useState</span><span>(</span><span>0</span><span>)</span><span>;</span>

  <span>return</span> <span>(</span>
    <span><span><span>&lt;</span></span><span>&gt;</span></span><span></span>
<span>      </span><span><span><span>&lt;</span>button</span> <span>onClick</span><span><span>=</span><span>{</span><span>(</span><span>)</span> <span>=&gt;</span> <span>setCount</span><span>(</span><span>(</span>c<span>)</span> <span>=&gt;</span> c <span>+</span> <span>1</span><span>)</span><span>}</span></span><span>&gt;</span></span><span>{</span>count<span>}</span><span><span><span>&lt;/</span>button</span><span>&gt;</span></span><span></span>
<span>      </span><span><span><span>&lt;</span><span>Library</span></span> <span>version</span><span><span>=</span><span>"</span>1<span>"</span></span> <span>/&gt;</span></span><span></span>
<span>    </span><span><span><span>&lt;/</span></span><span>&gt;</span></span>
  <span>)</span><span>;</span>
<span>}</span>

<span>const</span> <span>Library</span> <span>=</span> <span>React</span><span>.</span><span>memo</span><span>(</span><span>(</span><span>{</span> version <span>}</span><span>)</span> <span>=&gt;</span> <span>{</span>
  <span>return</span> <span><span><span>&lt;</span>h1</span><span>&gt;</span></span><span>The library version is </span><span>{</span>version<span>}</span><span><span><span>&lt;/</span>h1</span><span>&gt;</span></span><span>;</span>
<span>}</span><span>)</span><span>;</span>
</code></pre></div>
<p><code>React.memo</code> will see if props passed to a functional component have been updated or not. It loops through all the keys in previous props and next props, and sees if they're referential-ly equal to each other. It accepts a second argument as well to explicit perform this check.</p>
<div><pre><code><span>const</span> <span>Library</span> <span>=</span> <span>React</span><span>.</span><span>memo</span><span>(</span>
  <span>(</span><span>{</span> version <span>}</span><span>)</span> <span>=&gt;</span> <span>{</span>
    <span>return</span> <span><span><span>&lt;</span>h1</span><span>&gt;</span></span><span>The library version is </span><span>{</span>version<span>}</span><span><span><span>&lt;/</span>h1</span><span>&gt;</span></span><span>;</span>
  <span>}</span><span>,</span>
  <span>(</span>prevProps<span>,</span> nextProps<span>)</span> <span>=&gt;</span> prevProps<span>.</span><span>version</span> <span>===</span> nextProps<span>.</span><span>version</span>
<span>)</span><span>;</span>
</code></pre></div>
<p>Here we are telling <code>React.memo</code> that consider props to be equal if the 2nd argument returns <code>true</code>. So the function is anwering the question <code>are props the same?</code></p>
<p>One thing to note is that <code>React.memo</code> checks for reference updates and not value update. The "reference" to any variable may change even though the "value" remains same.</p>
<div><pre><code><span>let</span> a <span>=</span> <span>{</span> <span>version</span><span>:</span> <span>1</span> <span>}</span><span>;</span>

a <span>=</span> <span>{</span> <span>version</span><span>:</span> <span>1</span> <span>}</span><span>;</span>
</code></pre></div>
<p>In the above code, by virtue of re-assignment, we've caused the reference of <code>a</code> to change, even though the value is identical. React doesn't care for the value, but the reference. This is why we can't mutate variables as React wouldn't be able to tell whether it has been updated or not. And such reassignments can happen a lot of times! Let's consider the following example now.</p>
<div><pre><code><span>function</span> <span>MyComponent</span><span>(</span><span>)</span> <span>{</span>
  <span>const</span> <span>[</span>count<span>,</span> setCount<span>]</span> <span>=</span> <span>useState</span><span>(</span><span>0</span><span>)</span><span>;</span>

  <span>const</span> libraryData <span>=</span> <span>{</span> version<span>:</span> <span>"1"</span> <span>}</span><span>;</span>
  <span>return</span> <span>(</span>
    <span><span><span>&lt;</span></span><span>&gt;</span></span><span></span>
<span>      </span><span><span><span>&lt;</span>button</span> <span>onClick</span><span><span>=</span><span>{</span><span>(</span><span>)</span> <span>=&gt;</span> <span>setCount</span><span>(</span><span>(</span>c<span>)</span> <span>=&gt;</span> c <span>+</span> <span>1</span><span>)</span><span>}</span></span><span>&gt;</span></span><span>{</span>count<span>}</span><span><span><span>&lt;/</span>button</span><span>&gt;</span></span><span></span>
<span>      </span><span><span><span>&lt;</span><span>Library</span></span> <span>data</span><span><span>=</span><span>{</span>libraryData<span>}</span></span> <span>/&gt;</span></span><span></span>
<span>    </span><span><span><span>&lt;/</span></span><span>&gt;</span></span>
  <span>)</span><span>;</span>
<span>}</span>

<span>const</span> <span>Library</span> <span>=</span> <span>(</span><span>{</span> data<span>:</span> <span>{</span> version <span>}</span> <span>}</span><span>)</span> <span>=&gt;</span> <span>{</span>
  <span>return</span> <span><span><span>&lt;</span>h1</span><span>&gt;</span></span><span>The library version is </span><span>{</span>version<span>}</span><span><span><span>&lt;/</span>h1</span><span>&gt;</span></span><span>;</span>
<span>}</span><span>;</span>
</code></pre></div>
<p>Just like before, whenever the <code>count</code> state variable updates, <code>MyComponent</code> would re-render, due to which <code>Library</code> would re-render too. Even if we apply <code>React.memo</code> like before, it wouldn't help in this particular case.</p>
<div><pre><code><span>function</span> <span>MyComponent</span><span>(</span><span>)</span> <span>{</span>
  <span>const</span> <span>[</span>count<span>,</span> setCount<span>]</span> <span>=</span> <span>useState</span><span>(</span><span>0</span><span>)</span><span>;</span>

  <span>const</span> libraryData <span>=</span> <span>{</span> version<span>:</span> <span>"1"</span> <span>}</span><span>;</span>
  <span>return</span> <span>(</span>
    <span><span><span>&lt;</span></span><span>&gt;</span></span><span></span>
<span>      </span><span><span><span>&lt;</span>button</span> <span>onClick</span><span><span>=</span><span>{</span><span>(</span><span>)</span> <span>=&gt;</span> <span>setCount</span><span>(</span><span>(</span>c<span>)</span> <span>=&gt;</span> c <span>+</span> <span>1</span><span>)</span><span>}</span></span><span>&gt;</span></span><span>{</span>count<span>}</span><span><span><span>&lt;/</span>button</span><span>&gt;</span></span><span></span>
<span>      </span><span><span><span>&lt;</span><span>Library</span></span> <span>data</span><span><span>=</span><span>{</span>libraryData<span>}</span></span> <span>/&gt;</span></span><span></span>
<span>    </span><span><span><span>&lt;/</span></span><span>&gt;</span></span>
  <span>)</span><span>;</span>
<span>}</span>

<span>// ❌ Wouldn't work as reference of libraryData changes on each render</span>
<span>const</span> <span>Library</span> <span>=</span> <span>React</span><span>.</span><span>memo</span><span>(</span><span>(</span><span>{</span> data<span>:</span> <span>{</span> version <span>}</span> <span>}</span><span>)</span> <span>=&gt;</span> <span>{</span>
  <span>return</span> <span><span><span>&lt;</span>h1</span><span>&gt;</span></span><span>The library version is </span><span>{</span>version<span>}</span><span><span><span>&lt;/</span>h1</span><span>&gt;</span></span><span>;</span>
<span>}</span><span>)</span><span>;</span>
</code></pre></div>
<p>The reason for this is that we've passed an object literal, which would be created each time <code>MyComponent</code> updates. Same is true for functions that are created in-line.</p>
<div><pre><code><span>function</span> <span>MyComponent</span><span>(</span><span>)</span> <span>{</span>
  <span>const</span> <span>[</span>count<span>,</span> setCount<span>]</span> <span>=</span> <span>useState</span><span>(</span><span>0</span><span>)</span><span>;</span>

  <span>const</span> <span>onClick</span> <span>=</span> <span>(</span><span>)</span> <span>=&gt;</span> <span>alert</span><span>(</span><span>"You clicked!"</span><span>)</span><span>;</span>

  <span>return</span> <span>(</span>
    <span><span><span>&lt;</span></span><span>&gt;</span></span><span></span>
<span>      </span><span><span><span>&lt;</span>button</span> <span>onClick</span><span><span>=</span><span>{</span><span>(</span><span>)</span> <span>=&gt;</span> <span>setCount</span><span>(</span><span>(</span>c<span>)</span> <span>=&gt;</span> c <span>+</span> <span>1</span><span>)</span><span>}</span></span><span>&gt;</span></span><span>{</span>count<span>}</span><span><span><span>&lt;/</span>button</span><span>&gt;</span></span><span></span>
<span>      </span><span><span><span>&lt;</span><span>Library</span></span> <span>version</span><span><span>=</span><span>"</span>1<span>"</span></span> <span>onClick</span><span><span>=</span><span>{</span>onClick<span>}</span></span> <span>/&gt;</span></span><span></span>
<span>    </span><span><span><span>&lt;/</span></span><span>&gt;</span></span>
  <span>)</span><span>;</span>
<span>}</span>

<span>// ❌ Wouldn't work as reference of onClick changes on each render</span>
<span>const</span> <span>Library</span> <span>=</span> <span>React</span><span>.</span><span>memo</span><span>(</span><span>(</span><span>{</span> version<span>,</span> onClick <span>}</span><span>)</span> <span>=&gt;</span> <span>{</span>
  <span>return</span> <span><span><span>&lt;</span>h1</span> <span>onClick</span><span><span>=</span><span>{</span>onClick<span>}</span></span><span>&gt;</span></span><span>The library version is </span><span>{</span>version<span>}</span><span><span><span>&lt;/</span>h1</span><span>&gt;</span></span><span>;</span>
<span>}</span><span>)</span><span>;</span>
</code></pre></div>
<p>Each time <code>MyComponent</code> updates, a new function is created for <code>onClick</code> prop of <code>Library</code>. This can be fixed by some of the following techniques:</p>
<ol>
<li>Moving the said object/function outside of render of <code>MyComponent</code></li>
<li>Somehow memozing the value between renders.</li>
<li>Updating the checks performed by <code>React.memo</code> to compare the value and not just reference.</li>
</ol>
<p>For the first method, we can just move the object to global scope. This way the reference never changes.</p>
<div><pre><code><span>const</span> libraryData <span>=</span> <span>{</span> version<span>:</span> <span>"1"</span> <span>}</span><span>;</span>

<span>function</span> <span>MyComponent</span><span>(</span><span>)</span> <span>{</span>
  <span>const</span> <span>[</span>count<span>,</span> setCount<span>]</span> <span>=</span> <span>useState</span><span>(</span><span>0</span><span>)</span><span>;</span>

  <span>return</span> <span>(</span>
    <span><span><span>&lt;</span></span><span>&gt;</span></span><span></span>
<span>      </span><span><span><span>&lt;</span>button</span> <span>onClick</span><span><span>=</span><span>{</span><span>(</span><span>)</span> <span>=&gt;</span> <span>setCount</span><span>(</span><span>(</span>c<span>)</span> <span>=&gt;</span> c <span>+</span> <span>1</span><span>)</span><span>}</span></span><span>&gt;</span></span><span>{</span>count<span>}</span><span><span><span>&lt;/</span>button</span><span>&gt;</span></span><span></span>
<span>      </span><span><span><span>&lt;</span><span>Library</span></span> <span>data</span><span><span>=</span><span>{</span>libraryData<span>}</span></span> <span>/&gt;</span></span><span></span>
<span>    </span><span><span><span>&lt;/</span></span><span>&gt;</span></span>
  <span>)</span><span>;</span>
<span>}</span>

<span>// ✅ Works as reference of libraryData doesn't change</span>
<span>const</span> <span>Library</span> <span>=</span> <span>React</span><span>.</span><span>memo</span><span>(</span><span>(</span><span>{</span> data<span>:</span> <span>{</span> version <span>}</span> <span>}</span><span>)</span> <span>=&gt;</span> <span>{</span>
  <span>return</span> <span><span><span>&lt;</span>h1</span><span>&gt;</span></span><span>The library version is </span><span>{</span>version<span>}</span><span><span><span>&lt;/</span>h1</span><span>&gt;</span></span><span>;</span>
<span>}</span><span>)</span><span>;</span>
</code></pre></div>
<h4 id="usememo--usecallback"><a class="heading-permalink" href="https://bogas04.fyi/blog/2020/09/learning-reactjs-in-2020#usememo--usecallback" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text">useMemo &amp; useCallback</span></a></h4>
<p>Or you could update the way <code>Library</code> accepts version. Notice how earlier we were simply passing version as a prop instead of keeping it inside a data prop. Since reference to strings &amp; numbers don't change, our usage of <code>React.memo</code> would work as expected. The insight here is that you can design the way your component accepts props to avoid such pit-falls of referential equality checks. But this might not work always as your data needs might be different.</p>
<div><pre><code><span>function</span> <span>MyComponent</span><span>(</span><span>)</span> <span>{</span>
  <span>const</span> <span>[</span>count<span>,</span> setCount<span>]</span> <span>=</span> <span>useState</span><span>(</span><span>0</span><span>)</span><span>;</span>

  <span>return</span> <span>(</span>
    <span><span><span>&lt;</span></span><span>&gt;</span></span><span></span>
<span>      </span><span><span><span>&lt;</span>button</span> <span>onClick</span><span><span>=</span><span>{</span><span>(</span><span>)</span> <span>=&gt;</span> <span>setCount</span><span>(</span><span>(</span>c<span>)</span> <span>=&gt;</span> c <span>+</span> <span>1</span><span>)</span><span>}</span></span><span>&gt;</span></span><span>{</span>count<span>}</span><span><span><span>&lt;/</span>button</span><span>&gt;</span></span><span></span>
<span>      </span><span><span><span>&lt;</span><span>Library</span></span> <span>version</span><span><span>=</span><span>"</span>1<span>"</span></span> <span>/&gt;</span></span><span></span>
<span>    </span><span><span><span>&lt;/</span></span><span>&gt;</span></span>
  <span>)</span><span>;</span>
<span>}</span>

<span>// ✅ Works as reference of strings doesn't change</span>
<span>const</span> <span>Library</span> <span>=</span> <span>React</span><span>.</span><span>memo</span><span>(</span><span>(</span><span>{</span> version <span>}</span><span>)</span> <span>=&gt;</span> <span>{</span>
  <span>return</span> <span><span><span>&lt;</span>h1</span><span>&gt;</span></span><span>The library version is </span><span>{</span>version<span>}</span><span><span><span>&lt;/</span>h1</span><span>&gt;</span></span><span>;</span>
<span>}</span><span>)</span><span>;</span>
</code></pre></div>
<p>Second method can help in that case. To memoize the value, in functional components we can use advanced hooks like <code>React.useMemo</code> &amp; <code>React.useCallback</code>. Suppose we really need to pass <code>version</code> as a data object. We can ask React to memoize it between renders using <code>useMemo</code>. The second argument is a dependency array, just like <code>useEffect</code>. So here we are telling React to recompute <code>libraryData</code> whenver any item in the array passed as second argument changes. Empty array implies on component mount. So this way we can preserve the reference to <code>libraryData</code></p>
<div><pre><code><span>function</span> <span>MyComponent</span><span>(</span><span>)</span> <span>{</span>
  <span>const</span> <span>[</span>count<span>,</span> setCount<span>]</span> <span>=</span> <span>useState</span><span>(</span><span>0</span><span>)</span><span>;</span>

  <span>const</span> libraryData <span>=</span> <span>useMemo</span><span>(</span><span>(</span><span>)</span> <span>=&gt;</span> <span>(</span><span>{</span> version<span>:</span> <span>1</span> <span>}</span><span>)</span><span>,</span> <span>[</span><span>]</span><span>)</span><span>;</span>

  <span>return</span> <span>(</span>
    <span><span><span>&lt;</span></span><span>&gt;</span></span><span></span>
<span>      </span><span><span><span>&lt;</span>button</span> <span>onClick</span><span><span>=</span><span>{</span><span>(</span><span>)</span> <span>=&gt;</span> <span>setCount</span><span>(</span><span>(</span>c<span>)</span> <span>=&gt;</span> c <span>+</span> <span>1</span><span>)</span><span>}</span></span><span>&gt;</span></span><span>{</span>count<span>}</span><span><span><span>&lt;/</span>button</span><span>&gt;</span></span><span></span>
<span>      </span><span><span><span>&lt;</span><span>Library</span></span> <span>data</span><span><span>=</span><span>{</span>libraryData<span>}</span></span> <span>/&gt;</span></span><span></span>
<span>    </span><span><span><span>&lt;/</span></span><span>&gt;</span></span>
  <span>)</span><span>;</span>
<span>}</span>

<span>// ✅ Works as reference of libraryData is now memoized.</span>
<span>const</span> <span>Library</span> <span>=</span> <span>React</span><span>.</span><span>memo</span><span>(</span><span>(</span><span>{</span> data<span>:</span> <span>{</span> version <span>}</span> <span>}</span><span>)</span> <span>=&gt;</span> <span>{</span>
  <span>return</span> <span><span><span>&lt;</span>h1</span><span>&gt;</span></span><span>The library version is </span><span>{</span>version<span>}</span><span><span><span>&lt;/</span>h1</span><span>&gt;</span></span><span>;</span>
<span>}</span><span>)</span><span>;</span>
</code></pre></div>
<p><code>useCallback</code> is similar to <code>useMemo</code>, just that it returns a callable function instead. We can use this for functions.</p>
<div><pre><code><span>function</span> <span>MyComponent</span><span>(</span><span>)</span> <span>{</span>
  <span>const</span> <span>[</span>count<span>,</span> setCount<span>]</span> <span>=</span> <span>useState</span><span>(</span><span>0</span><span>)</span><span>;</span>

  <span>const</span> onClick <span>=</span> <span>useCallback</span><span>(</span><span>(</span><span>)</span> <span>=&gt;</span> <span>alert</span><span>(</span><span>"You clicked!"</span><span>)</span><span>,</span> <span>[</span><span>]</span><span>)</span><span>;</span>

  <span>return</span> <span>(</span>
    <span><span><span>&lt;</span></span><span>&gt;</span></span><span></span>
<span>      </span><span><span><span>&lt;</span>button</span> <span>onClick</span><span><span>=</span><span>{</span><span>(</span><span>)</span> <span>=&gt;</span> <span>setCount</span><span>(</span><span>(</span>c<span>)</span> <span>=&gt;</span> c <span>+</span> <span>1</span><span>)</span><span>}</span></span><span>&gt;</span></span><span>{</span>count<span>}</span><span><span><span>&lt;/</span>button</span><span>&gt;</span></span><span></span>
<span>      </span><span><span><span>&lt;</span><span>Library</span></span> <span>version</span><span><span>=</span><span>"</span>1<span>"</span></span> <span>onClick</span><span><span>=</span><span>{</span>onClick<span>}</span></span> <span>/&gt;</span></span><span></span>
<span>    </span><span><span><span>&lt;/</span></span><span>&gt;</span></span>
  <span>)</span><span>;</span>
<span>}</span>

<span>// ✅ Works as reference of onClick is now memoized.</span>
<span>const</span> <span>Library</span> <span>=</span> <span>React</span><span>.</span><span>memo</span><span>(</span><span>(</span><span>{</span> version<span>,</span> onClick <span>}</span><span>)</span> <span>=&gt;</span> <span>{</span>
  <span>return</span> <span><span><span>&lt;</span>h1</span> <span>onClick</span><span><span>=</span><span>{</span>onClick<span>}</span></span><span>&gt;</span></span><span>The library version is </span><span>{</span>version<span>}</span><span><span><span>&lt;/</span>h1</span><span>&gt;</span></span><span>;</span>
<span>}</span><span>)</span><span>;</span>
</code></pre></div>
<p>In fact, you can implement <code>useCallback</code> using <code>useMemo</code> as the latter works for any type of value.</p>
<div><pre><code><span>const</span> <span>useCallback</span> <span>=</span> <span>(</span>fn<span>,</span> dependencyArray<span>)</span> <span>=&gt;</span> <span>useMemo</span><span>(</span><span>(</span><span>)</span> <span>=&gt;</span> fn<span>,</span> dependencyArray<span>)</span><span>;</span>
</code></pre></div>
<p>The last method is to just change the way <code>React.memo</code> performs the check. Though this can go pretty nasty as the number of props increase and nesting of the keys increase. And there's no neat way to do it for functions.</p>
<div><pre><code><span>function</span> <span>MyComponent</span><span>(</span><span>)</span> <span>{</span>
  <span>const</span> <span>[</span>count<span>,</span> setCount<span>]</span> <span>=</span> <span>useState</span><span>(</span><span>0</span><span>)</span><span>;</span>

  <span>const</span> libraryData <span>=</span> <span>{</span> version<span>:</span> <span>"1"</span> <span>}</span><span>;</span>
  <span>return</span> <span>(</span>
    <span><span><span>&lt;</span></span><span>&gt;</span></span><span></span>
<span>      </span><span><span><span>&lt;</span>button</span> <span>onClick</span><span><span>=</span><span>{</span><span>(</span><span>)</span> <span>=&gt;</span> <span>setCount</span><span>(</span><span>(</span>c<span>)</span> <span>=&gt;</span> c <span>+</span> <span>1</span><span>)</span><span>}</span></span><span>&gt;</span></span><span>{</span>count<span>}</span><span><span><span>&lt;/</span>button</span><span>&gt;</span></span><span></span>
<span>      </span><span><span><span>&lt;</span><span>Library</span></span> <span>data</span><span><span>=</span><span>{</span>libraryData<span>}</span></span> <span>/&gt;</span></span><span></span>
<span>    </span><span><span><span>&lt;/</span></span><span>&gt;</span></span>
  <span>)</span><span>;</span>
<span>}</span>

<span>// ✅ Works as we're now comparing individual key of object</span>
<span>const</span> <span>Library</span> <span>=</span> <span>React</span><span>.</span><span>memo</span><span>(</span>
  <span>(</span><span>{</span> data<span>:</span> <span>{</span> version <span>}</span> <span>}</span><span>)</span> <span>=&gt;</span> <span>{</span>
    <span>return</span> <span><span><span>&lt;</span>h1</span><span>&gt;</span></span><span>The library version is </span><span>{</span>version<span>}</span><span><span><span>&lt;/</span>h1</span><span>&gt;</span></span><span>;</span>
  <span>}</span><span>,</span>
  <span>(</span>prevProps<span>,</span> nextProps<span>)</span> <span>=&gt;</span> prevProps<span>.</span><span>data</span><span>.</span><span>version</span> <span>!==</span> nextProps<span>.</span><span>data</span><span>.</span><span>version</span>
<span>)</span><span>;</span>
</code></pre></div>
<p><strong>NOTE:</strong> These are advanced optimizations and you should use them only if you've an actual performance regression. More often than not, the extra work done in these optimizations might give very little gains with the cost of code complexity and potential to introduce bugs. Each memoization technique described here requries extra computation (<code>React.memo</code> loops throught all props and checks their reference change), memory usage (To memoize is to store data) between renders, so the benefit would only come if the value you're trying to memozie is too expensive to calculate (some highly complicated data manipulation on an array of 1000 items) or the component you're planning to prevent re-renders for has a complicated deeply nested UI to render. In above cases it makes no sense as <code>&lt;h1 /&gt;</code> is fairly simple component and <code>libraryData</code> is a very small object. So unless you have a performance problem caused by re-renders, you shouldn't wrap variables in <code>useMemo</code> and components in <code>React.memo</code></p>
<h3 id="reactpurecomponent"><a class="heading-permalink" href="https://bogas04.fyi/blog/2020/09/learning-reactjs-in-2020#reactpurecomponent" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text">React.PureComponent</span></a></h3>
<p><code>React.memo</code> and the hooks like <code>useMemo</code> and <code>useCallback</code> only work for functional components. What about class components?</p>
<p>Let's first take our above example to a class-y world.</p>
<div><pre><code><span>class</span> <span>MyComponent</span> <span>extends</span> <span>React</span><span>.</span><span><span>Component</span></span> <span>{</span>
  state <span>=</span> <span>{</span> count<span>:</span> <span>0</span> <span>}</span><span>;</span>

  <span>render</span> <span>(</span><span>)</span> <span>{</span>
   <span>const</span> libraryData <span>=</span> <span>{</span> version<span>:</span> <span>"1"</span> <span>}</span><span>;</span>
    <span>return</span> <span>(</span>
      <span><span><span>&lt;</span></span><span>&gt;</span></span><span></span>
<span>        </span><span><span><span>&lt;</span>button</span>
          <span>onClick</span><span><span>=</span><span>{</span><span>(</span><span>)</span> <span>=&gt;</span> <span>this</span><span>.</span><span>setState</span><span>(</span>s <span>=&gt;</span> <span>(</span><span>{</span> count<span>:</span> s<span>.</span><span>count</span> <span>+</span> <span>1</span> <span>}</span><span>)</span><span>}</span></span>
        <span>&gt;</span></span><span></span>
<span>          </span><span>{</span>count<span>}</span><span></span>
<span>        </span><span><span><span>&lt;/</span>button</span><span>&gt;</span></span><span></span>
<span>        </span><span><span><span>&lt;</span><span>Library</span></span> <span>data</span><span><span>=</span><span>{</span>libraryData<span>}</span></span> <span>/&gt;</span></span><span></span>
<span>      </span><span><span><span>&lt;/</span></span><span>&gt;</span></span>
    <span>)</span><span>;</span>
  <span>}</span>
<span>}</span>

<span>class</span> <span>Library</span> <span>extends</span> <span>React</span><span>.</span><span><span>Component</span></span> <span>{</span>
  <span>render</span> <span>(</span><span>)</span> <span>{</span>
    <span>const</span> <span>{</span> version <span>}</span> <span>=</span> <span>this</span><span>.</span><span>props</span><span>.</span><span>data</span><span>;</span>
    <span>return</span> <span><span><span>&lt;</span>h1</span><span>&gt;</span></span><span>The library version is </span><span>{</span>version<span>}</span><span><span><span>&lt;/</span>h1</span><span>&gt;</span></span><span>;</span>
  <span>}</span>
<span>)</span><span>;</span>
</code></pre></div>
<p>Class based components have access to a life cycle method <code>shouldComponentUpdate</code>. We can guess from the name that it's similar to the second argument of <code>React.memo</code> above.</p>
<div><pre><code><span>class</span> <span>MyComponent</span> <span>extends</span> <span>React</span><span>.</span><span><span>Component</span></span> <span>{</span>
  state <span>=</span> <span>{</span> count<span>:</span> <span>0</span> <span>}</span><span>;</span>

  <span>render</span> <span>(</span><span>)</span> <span>{</span>
   <span>const</span> libraryData <span>=</span> <span>{</span> version<span>:</span> <span>"1"</span> <span>}</span><span>;</span>
    <span>return</span> <span>(</span>
      <span><span><span>&lt;</span></span><span>&gt;</span></span><span></span>
<span>        </span><span><span><span>&lt;</span>button</span>
          <span>onClick</span><span><span>=</span><span>{</span><span>(</span><span>)</span> <span>=&gt;</span> <span>this</span><span>.</span><span>setState</span><span>(</span>s <span>=&gt;</span> <span>(</span><span>{</span> count<span>:</span> s<span>.</span><span>count</span> <span>+</span> <span>1</span> <span>}</span><span>)</span><span>}</span></span>
        <span>&gt;</span></span><span></span>
<span>          </span><span>{</span>count<span>}</span><span></span>
<span>        </span><span><span><span>&lt;/</span>button</span><span>&gt;</span></span><span></span>
<span>        </span><span><span><span>&lt;</span><span>Library</span></span> <span>data</span><span><span>=</span><span>{</span>libraryData<span>}</span></span> <span>/&gt;</span></span><span></span>
<span>      </span><span><span><span>&lt;/</span></span><span>&gt;</span></span>
    <span>)</span><span>;</span>
  <span>}</span>
<span>}</span>

<span>class</span> <span>Library</span> <span>extends</span> <span>React</span><span>.</span><span><span>Component</span></span> <span>{</span>
  <span>shouldComponentUpdate</span><span>(</span>nextProps<span>,</span> nextState<span>)</span> <span>{</span>
    <span>return</span> <span>this</span><span>.</span><span>props</span><span>.</span><span>data</span><span>.</span><span>version</span> <span>!==</span> nextProps<span>.</span><span>data</span><span>.</span><span>version</span><span>;</span>
  <span>}</span>
  <span>render</span> <span>(</span><span>)</span> <span>{</span>
    <span>const</span> <span>{</span> version <span>}</span> <span>=</span> <span>this</span><span>.</span><span>props</span><span>.</span><span>data</span><span>;</span>
    <span>return</span> <span><span><span>&lt;</span>h1</span><span>&gt;</span></span><span>The library version is </span><span>{</span>version<span>}</span><span><span><span>&lt;/</span>h1</span><span>&gt;</span></span><span>;</span>
  <span>}</span>
<span>)</span><span>;</span>
</code></pre></div>
<p>It's different in two ways than <code>React.memo</code>. Firstly, it has access to <code>nextState</code> so we can add checks for state changes. This can be helpful if a key in <code>this.state</code> is an object or function and you can't determine whether a state update is needed whenever you set it. Secondly, it is expecting answer to <code>should component update?</code> and not <code>are props the same?</code>. Other than that it's pretty much the same. You can imagine writing it by hand and having a dozen of checks for a large component can be tedious and error-prone. If only we had a default behaviour of <code>React.memo</code> for classes. Enter <code>React.PureComponent</code></p>
<p>Just like <code>React.Component</code>, <code>React.PureComponent</code> is another class you can extend from to create your component. It behaves just like a regular component, but has a <code>shouldComponentUpdate</code> lifecycle method implemented for you.</p>
<div><pre><code><span>class</span> <span>MyComponent</span> <span>extends</span> <span>React</span><span>.</span><span><span>Component</span></span> <span>{</span>
  state <span>=</span> <span>{</span> count<span>:</span> <span>0</span> <span>}</span><span>;</span>

  <span>render</span> <span>(</span><span>)</span> <span>{</span>
    <span>return</span> <span>(</span>
      <span><span><span>&lt;</span></span><span>&gt;</span></span><span></span>
<span>        </span><span><span><span>&lt;</span>button</span>
          <span>onClick</span><span><span>=</span><span>{</span><span>(</span><span>)</span> <span>=&gt;</span> <span>this</span><span>.</span><span>setState</span><span>(</span>s <span>=&gt;</span> <span>(</span><span>{</span> count<span>:</span> s<span>.</span><span>count</span> <span>+</span> <span>1</span> <span>}</span><span>)</span><span>}</span></span>
        <span>&gt;</span></span><span></span>
<span>          </span><span>{</span>count<span>}</span><span></span>
<span>        </span><span><span><span>&lt;/</span>button</span><span>&gt;</span></span><span></span>
<span>        </span><span><span><span>&lt;</span><span>Library</span></span> <span>version</span><span><span>=</span><span>"</span>1<span>"</span></span> <span>/&gt;</span></span><span></span>
<span>      </span><span><span><span>&lt;/</span></span><span>&gt;</span></span>
    <span>)</span><span>;</span>
  <span>}</span>
<span>}</span>

<span>// ✅ Works as reference of this.props.version doesn't change as it's a string</span>
<span>class</span> <span>Library</span> <span>extends</span> <span>React</span><span>.</span><span><span>PureComponent</span></span> <span>{</span>
  <span>render</span> <span>(</span><span>)</span> <span>{</span>
    <span>const</span> <span>{</span> version <span>}</span> <span>=</span> <span>this</span><span>.</span><span>props</span><span>;</span>
    <span>return</span> <span><span><span>&lt;</span>h1</span><span>&gt;</span></span><span>The library version is </span><span>{</span>version<span>}</span><span><span><span>&lt;/</span>h1</span><span>&gt;</span></span><span>;</span>
  <span>}</span>
<span>)</span><span>;</span>
</code></pre></div>
<p>And just like <code>React.memo</code> it would fail if the said prop is an object or function that updates in each render. However, we don't really have a simple way to memoize these variables like <code>useMemo</code>. You can instead define a class property to move it out of scope render method.</p>
<div><pre><code><span>class</span> <span>MyComponent</span> <span>extends</span> <span>React</span><span>.</span><span><span>Component</span></span> <span>{</span>
  state <span>=</span> <span>{</span> count<span>:</span> <span>0</span> <span>}</span><span>;</span>

  libraryData <span>=</span> <span>{</span> version<span>:</span> <span>"1"</span> <span>}</span><span>;</span>

  <span>render</span> <span>(</span><span>)</span> <span>{</span>
    <span>return</span> <span>(</span>
      <span><span><span>&lt;</span></span><span>&gt;</span></span><span></span>
<span>        </span><span><span><span>&lt;</span>button</span>
          <span>onClick</span><span><span>=</span><span>{</span><span>(</span><span>)</span> <span>=&gt;</span> <span>this</span><span>.</span><span>setState</span><span>(</span>s <span>=&gt;</span> <span>(</span><span>{</span> count<span>:</span> s<span>.</span><span>count</span> <span>+</span> <span>1</span> <span>}</span><span>)</span><span>}</span></span>
        <span>&gt;</span></span><span></span>
<span>          </span><span>{</span>count<span>}</span><span></span>
<span>        </span><span><span><span>&lt;/</span>button</span><span>&gt;</span></span><span></span>
<span>        </span><span><span><span>&lt;</span><span>Library</span></span> <span>data</span><span><span>=</span><span>{</span><span>this</span><span>.</span><span>libraryData</span><span>}</span></span> <span>/&gt;</span></span><span></span>
<span>      </span><span><span><span>&lt;/</span></span><span>&gt;</span></span>
    <span>)</span><span>;</span>
  <span>}</span>
<span>}</span>

<span>class</span> <span>Library</span> <span>extends</span> <span>React</span><span>.</span><span><span>Component</span></span> <span>{</span>
  <span>render</span> <span>(</span><span>)</span> <span>{</span>
    <span>const</span> <span>{</span> version <span>}</span> <span>=</span> <span>this</span><span>.</span><span>props</span><span>.</span><span>data</span><span>;</span>
    <span>return</span> <span><span><span>&lt;</span>h1</span><span>&gt;</span></span><span>The library version is </span><span>{</span>version<span>}</span><span><span><span>&lt;/</span>h1</span><span>&gt;</span></span><span>;</span>
  <span>}</span>
<span>)</span><span>;</span>
</code></pre></div>
<p><strong>NOTE:</strong> Writing <code>shouldComponentUpdate</code> by hand can cause more harm if a bug in logic prevents component from re-rendering. Relying on <code>PureComponent</code> is preferred, however if the component is simple, a re-render might be as good as comparison checks before render.</p>
]]></content:encoded>
</item>

<item>
<title><![CDATA[My macOS setup]]></title>
<link>https://bogas04.fyi/blog/2020/04/my-macos-setup</link>
<guid>https://bogas04.fyi/blog/2020/04/my-macos-setup</guid>
<pubDate>Fri, 03 Apr 2020 07:55:58 GMT</pubDate>
<description><![CDATA[Stuff I do while setting up a new mac]]></description>
<content:encoded><![CDATA[<p><a class="blog-image-link" href="https://bogas04.fyi/img/blog/macos.jpg" target="_blank" rel="noopener noreferrer"><img src="https://bogas04.fyi/img/blog/macos.jpg" alt="Picture of a macbook"></a></p>
<h2 id="preferences"><a class="heading-permalink" href="https://bogas04.fyi/blog/2020/04/my-macos-setup#preferences" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text">Preferences</span></a></h2>
<p>I dislike macOS's fullscreen mode, so in order to get maximum screen real estate, I autohide menu bar and dock.</p>
<h3 id="autohide-menu-bar"><a class="heading-permalink" href="https://bogas04.fyi/blog/2020/04/my-macos-setup#autohide-menu-bar" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text">Autohide menu bar</span></a></h3>
<p>Refer to <a href="https://www.cnet.com/how-to/how-to-hide-the-menu-bar-in-os-x-el-capitan/">this</a> article.</p>
<h3 id="autohide-dock--disable-recent-applications"><a class="heading-permalink" href="https://bogas04.fyi/blog/2020/04/my-macos-setup#autohide-dock--disable-recent-applications" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text">Autohide dock &amp; disable recent applications</span></a></h3>
<p>I also like a clean setup, so I keep only essential items in the dock for quick access, for rest I use spotlight.</p>
<p>Refer to <a href="https://www.cnet.com/how-to/macos-mojave-shows-recent-apps-in-the-dock-heres-how-to-hide-them/">this</a> article.</p>
<h2 id="git-default-push-to-current-branch"><a class="heading-permalink" href="https://bogas04.fyi/blog/2020/04/my-macos-setup#git-default-push-to-current-branch" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text">Git default push to current branch</span></a></h2>
<div><pre><code><span>git</span> config push.default current <span>--global</span>
</code></pre></div>
<h2 id="oh-my-zsh-with-auto-suggest"><a class="heading-permalink" href="https://bogas04.fyi/blog/2020/04/my-macos-setup#oh-my-zsh-with-auto-suggest" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text">Oh My ZSH with Auto Suggest</span></a></h2>
<p><a href="https://ohmyz.sh/">Oh my ZSH</a></p>
<p><a href="https://github.com/zsh-users/zsh-autosuggestions/blob/master/INSTALL.md#oh-my-zsh">zsh-autosuggestions plugin</a></p>
<h2 id="keyboard-stuff"><a class="heading-permalink" href="https://bogas04.fyi/blog/2020/04/my-macos-setup#keyboard-stuff" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text">Keyboard stuff</span></a></h2>
<ul>
<li>Disable <code>cmd+option+space</code> for spotlight history (System Preferences -&gt; Spotlight -&gt; Keyboard Shortcuts)</li>
</ul>
<p>Spotlight history is of no good use really, and that key combination can be utilized for a better purpose that we'll talk about later.</p>
<p><a class="blog-image-link" href="https://bogas04.fyi/img/blog/spotlight-history.png" target="_blank" rel="noopener noreferrer"><img src="https://bogas04.fyi/img/blog/spotlight-history.png" alt="Screenshot of spotlight keyboard settings"></a></p>
<ul>
<li>Use Caps lock as Escape (System Preferences -&gt; Keyboard -&gt; Modifier Keys)</li>
</ul>
<p>As a vim user, I'm used to keeping Caps Lock as Escape key.</p>
<p><a class="blog-image-link" href="https://bogas04.fyi/img/blog/caps-escape.png" target="_blank" rel="noopener noreferrer"><img src="https://bogas04.fyi/img/blog/caps-escape.png" alt="Screenshot of capslock modifier"></a></p>
<ul>
<li>Turn on key repeating</li>
</ul>
<div><pre><code><span># Open Terminal.app and past the following command.</span>
defaults <span>write</span> <span>-g</span> ApplePressAndHoldEnabled <span>-bool</span> <span>false</span>
</code></pre></div>
<p>I don't know why this isn't the default behaviour. I don't have much use for macOS's character suggestions on holding a key.</p>
<h2 id="expanded-touchbar"><a class="heading-permalink" href="https://bogas04.fyi/blog/2020/04/my-macos-setup#expanded-touchbar" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text">Expanded TouchBar</span></a></h2>
<p>I prefer expanded touch bar over app specific touchbar.
System Preferences &gt; Keyboard &gt; "Touch Bar shows" - Expanded Control Strip.</p>
<h2 id="trackpad-stuff"><a class="heading-permalink" href="https://bogas04.fyi/blog/2020/04/my-macos-setup#trackpad-stuff" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text">Trackpad stuff</span></a></h2>
<h3 id="enable-tap-to-click-system-preferences---trackpad"><a class="heading-permalink" href="https://bogas04.fyi/blog/2020/04/my-macos-setup#enable-tap-to-click-system-preferences---trackpad" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text">Enable tap to click (System Preferences -&gt; Trackpad)</span></a></h3>
<p>I prefer tap over physical clicks.</p>
<h3 id="increase-cursor-size-system-preferences---accessibility---display"><a class="heading-permalink" href="https://bogas04.fyi/blog/2020/04/my-macos-setup#increase-cursor-size-system-preferences---accessibility---display" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text">Increase cursor size (System Preferences -&gt; Accessibility -&gt; Display)</span></a></h3>
<p>A big cursor is easier to find and makes things easy to move around.</p>
<ul>
<li>Enable dragging with three fingers (System Preferences -&gt; Accessibility -&gt; Trackpad -&gt; Trackpad Options)</li>
<li>Click and hold is worse experience in my opinion.</li>
</ul>
<h2 id="application-stuff"><a class="heading-permalink" href="https://bogas04.fyi/blog/2020/04/my-macos-setup#application-stuff" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text">Application stuff</span></a></h2>
<h3 id="configure-spotlight-to-not-index-a-lot-of-stuff"><a class="heading-permalink" href="https://bogas04.fyi/blog/2020/04/my-macos-setup#configure-spotlight-to-not-index-a-lot-of-stuff" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text">Configure spotlight to not index a lot of stuff.</span></a></h3>
<p>In my setup, I don't need use spotlight to open files, so indexing them (<em>cough</em> <code>node_modules</code> <em>cough</em>) is unnecessary waste of resources.</p>
<h3 id="install-rectangle"><a href="https://bogas04.fyi/blog/2020/04/my-macos-setup#install-rectangle" aria-hidden="true" tabindex="-1"><span>🔗</span></a>Install <a href="https://rectangleapp.com/">Rectangle</a></h3>
<p>This window management utility works with newer versions of macOS (even though now macOS supports tiling, it still sucks).
Configure it to use <code>cmd+option+arrow-key</code> for top/left/right/bottom and <code>cmd+option+space</code> for maximize</p>
<h3 id="install-maccy"><a href="https://bogas04.fyi/blog/2020/04/my-macos-setup#install-maccy" aria-hidden="true" tabindex="-1"><span>🔗</span></a>Install <a href="https://github.com/p0deje/Maccy">Maccy</a></h3>
<p>Clipboard management of my choice. I've started accepting the default options for my peace of mind.</p>
<h2 id="dot-files"><a class="heading-permalink" href="https://bogas04.fyi/blog/2020/04/my-macos-setup#dot-files" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text">dot-files</span></a></h2>
<p>If you're interested in my dot-files, you can view them <a href="https://github.com/bogas04/dot-files">here</a>.</p>
]]></content:encoded>
</item>

<item>
<title><![CDATA[Monorepos, lets talk about it]]></title>
<link>https://bogas04.fyi/blog/2019/09/monorepos-lets-talk-about-it</link>
<guid>https://bogas04.fyi/blog/2019/09/monorepos-lets-talk-about-it</guid>
<pubDate>Tue, 17 Sep 2019 07:55:58 GMT</pubDate>
<description><![CDATA[Recall the days when you were just introduced to git or a similar type ofversion control system. I’m guessing you must have faced some…]]></description>
<content:encoded><![CDATA[<p><a class="blog-image-link" href="https://bogas04.fyi/img/blog/1__zWhHZUDWuxJwfEoumC1__OQ.png" target="_blank" rel="noopener noreferrer"><img src="https://bogas04.fyi/img/blog/1__zWhHZUDWuxJwfEoumC1__OQ.png" alt="Image credits: undraw"></a></p>
<p>Recall the days when you were just introduced to <code>git</code> or a similar type of version control system. I’m guessing you must have faced some friction initially, how it breaks your flow, how you just can’t merge to master without rebasing/merging changes in first.</p>
<p>Despite that, you might agree today that it’s actually very helpful in collaborating with the team, and those pain points were necessary to get here.</p>
<p>Monorepos are somewhat similar.</p>
<p>While git was solving problems around managing single codebase with multiple team members or just better versioning, Monorepo kind of does the same but for multiple projects/codebases.</p>
<h3 id="the-what"><a class="heading-permalink" href="https://bogas04.fyi/blog/2019/09/monorepos-lets-talk-about-it#the-what" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text">The what.</span></a></h3>
<blockquote>
<p>Is Monorepo that cool font I see on&nbsp;Twitter?</p>
</blockquote>
<p><a class="blog-image-link" href="https://bogas04.fyi/img/blog/1__ZzlBaQH6w1BgwZdo3bIYRQ.png" target="_blank" rel="noopener noreferrer"><img src="https://bogas04.fyi/img/blog/1__ZzlBaQH6w1BgwZdo3bIYRQ.png" alt="Image credits: undraw"></a></p>
<p>Before diving into the topic, let’s first understand what Monorepo truly means. This is what Wikipedia has to say:</p>
<blockquote>
<p>In revision control systems, a Monorepo is a software development strategy where code for many projects are stored in the same repository.</p>
</blockquote>
<p>In other words, your ‘Work’ folder is close to what a Monorepo would look like. It would have packages that deal with server, web app, native app, documentation, etc.</p>
<p>This is different from a ‘monolith’ where all your application logic is<br>
centralized to one entry point as opposed to distributed services (microservices).</p>
<p>While code for various services would sit in a single repository, it doesn’t mean it would be deployed as a single entity, just like your ‘Work’ folder. Individual projects have separate life-cycles.</p>
<h3 id="the-why"><a class="heading-permalink" href="https://bogas04.fyi/blog/2019/09/monorepos-lets-talk-about-it#the-why" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text">The why.</span></a></h3>
<blockquote>
<p>So, do I just <code>git add</code> my entire ‘Work’&nbsp;folder?</p>
</blockquote>
<blockquote>
<p>“Why would you want to do this? Whatever happened to separation of concern?”</p>
</blockquote>
<p>There are several arguments both in favour and against Monorepos. And I don’t mean “Oh Google uses it” kind of arguments. This blog will give a sneak-peek into our problems and Monorepo’s solutions to them.</p>
<p>Regardless, I recommend that you identify the problems your codebase is facing, and see if Monorepo is truly the answer to those.</p>
<h3 id="the-story"><a class="heading-permalink" href="https://bogas04.fyi/blog/2019/09/monorepos-lets-talk-about-it#the-story" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text">The story.</span></a></h3>
<p>Before moving to Monorepo, we as a team worked on 3 codebases at the same time;</p>
<ul>
<li><strong>dweb</strong> (Desktop website of Swiggy)</li>
<li><strong>mweb</strong> (Mobile website of Swiggy)</li>
<li><strong>service</strong> (API proxy NodeJS middleware, used by dweb and mweb)</li>
</ul>
<p>When I say work, I mean writing features, updating build pipeline, reviewing code and fixing bugs.</p>
<p>As the codebases grew, we recognized some patterns:</p>
<p><a class="blog-image-link" href="https://bogas04.fyi/img/blog/1____L__bUfSLVT6EboXRO7SSGg.png" target="_blank" rel="noopener noreferrer"><img src="https://bogas04.fyi/img/blog/1____L__bUfSLVT6EboXRO7SSGg.png" alt="Image credits:&nbsp;undraw"></a></p>
<ul>
<li>Features written on mweb, while dissimilar enough to not to be dragged and dropped to dweb, held enough similarities to be broken into reusable parts.</li>
<li>Fixes that go on mweb are also needed on dweb.</li>
<li>Code reviewers often ended up reviewing the same code (between mweb and dweb) in a slightly different context.</li>
<li>Code review changes on dweb are also relevant to mweb</li>
<li>Changes to contracts of service, a common dependency, are also needed to be individually coded, tested, and reviewed.</li>
<li>Updating dependencies like <a href="https://reactjs.org/">React</a>/<a href="https://webpack.js.org/">Webpack</a>/<a href="https://babeljs.io/">Babel</a> becomes cumbersome between the two codebases.</li>
<li>Conventions are difficult to enforce between the three repositories. One has an older version of <a href="https://eslint.org/">ESLint</a>, one hasn’t been updated when new lint rules were added, one is still using old test runner.</li>
<li>Attempts to make a new repository to keep common code failed due to the amount of setup and code management. Imagine working with multiple team members on multiple repositories with multiple Pull Requests.</li>
</ul>
<p>As you can see, while the projects are very different (check out <a href="https://portal-sentry.swiggyapp.com/settings/swiggy/go-front-staging/keys/">swiggy.com</a> on your desktop and mobile to realize that), they still have quite a lot of common code interactions.</p>
<blockquote>
<p>Bike-shedding: Have you tried <a href="https://www.swiggy.com?utm_source=medium">Swiggy</a> website on your desktop or mobile browser? We would love to hear your feedback!</p>
</blockquote>
<h3 id="the-how"><a class="heading-permalink" href="https://bogas04.fyi/blog/2019/09/monorepos-lets-talk-about-it#the-how" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text">The how.</span></a></h3>
<p><a class="blog-image-link" href="https://bogas04.fyi/img/blog/1__0WjBWfdkbcob39FMklwp7A.png" target="_blank" rel="noopener noreferrer"><img src="https://bogas04.fyi/img/blog/1__0WjBWfdkbcob39FMklwp7A.png" alt="Logo of Lerna"></a></p>
<p><a href="https://lerna.js.org/">https://lerna.js.org/</a></p>
<p>Depending on your ecosystem, there will be different tools to help you with maintaining a Monorepo. You can obviously go vanilla and just use different folders per project. We use <a href="https://lerna.js.org/">Lerna</a> for maintaining our JavaScript codebase.</p>
<p>Thanks to its community, there’s a <a href="https://github.com/lerna/lerna/tree/master/commands/publish">lot</a> <a href="https://github.com/lerna/lerna/blob/master/FAQ.md">of</a> <a href="https://lerna.js.org/#commands">documentation</a> and <a href="https://medium.com/mitterio/multirepo-to-lerna-js-monorepo-80f6657cb443">help</a> for Lerna <a href="https://github.com/lerna/lerna/blob/master/doc/troubleshooting.md">related</a> <a href="https://github.com/lerna/lerna/blob/master/doc/guides.md">queries</a>.</p>
<div><pre><code><span># Install lerna globally</span>
<span>npm</span> i <span>-g</span> lerna

<span># Change directory to your work folder</span>
<span>cd</span> ~/Work

<span># Make the folder you want to keep your monorepo in</span>
<span>mkdir</span> portal-web

<span># Change directory to monorepo folder</span>
<span>cd</span> portal-web

<span># Initialize lerna (it will handle `git init`)</span>
lerna init

<span># Commit the changes</span>
<span>git</span> <span>add</span> <span>.</span> <span>&amp;&amp;</span> <span>git</span> commit <span>-m</span> <span>"Initial commit"</span>

<span># Import other packages (https://github.com/lerna/lerna/tree/master/commands/import)</span>
lerna <span>import</span> ~/Work/portal-mweb

<span># That's pretty much it!</span>

<span># Fun fact: If you want to rename your package, simply rename the folder before importing.</span>
<span># Fun fact 2: You might need to flatten out the commits in most cases (https://github.com/lerna/lerna/tree/master/commands/import#--flatten)</span>
</code></pre></div>
<p>You may use <a href="https://gist.github.com/bogas04/874731db80967c040209fea396bf7804">above scripts</a> to import existing repositories to a lerna based monorepo.</p>
<p>Running scripts from the root has been made simpler using these handy <a href="https://docs.npmjs.com/misc/scripts">npm scripts</a>.</p>
<p>These scripts allow for convenient way to invoke package scripts from root folder</p>
<p>Since our packages are hosted in <a href="https://verdaccio.org/">internal npm registry</a>, we inject a&nbsp;.npmrc in our <a href="https://jenkins.io/">Jenkins</a> build the pipeline to avoid committing the authToken.</p>
<p>A script to find all scoped dependencies of a project</p>
<div><pre><code><span># Install monorepo dependencies from internal npm registry</span>
<span>npm</span> i <span><span>`</span><span>..</span>/<span>..</span>/scripts/scope-packages.js @portal<span>`</span></span>

<span># Fun fact:</span>
<span># `npm i &lt;package-name&gt;` would also install other dependencies if they aren't present in node_modules,</span>
<span># along with the mentioned &lt;package-name&gt;</span>

<span># Fun fact 2:</span>
<span># In presence of package-lock.json, `npm i` would use those version numbers instead of fetching the latest ones</span>
<span># This essentially makes it a hybrid of `npm i` and `npm ci`</span>
</code></pre></div>
<p>One interesting thing about <a href="https://lerna.js.org/">Lerna</a> is that it <a href="https://gist.github.com/bogas04/8c9702aba064b03b1162a0058c7b8f98">doesn’t</a> want private packages to be part of the <code>package-lock.json.</code> This means we can’t just simply use <code>npm ci</code>. We use this bash script to get past that.</p>
<h3 id="the-happypart"><a class="heading-permalink" href="https://bogas04.fyi/blog/2019/09/monorepos-lets-talk-about-it#the-happypart" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text">The happy&nbsp;part.</span></a></h3>
<p>Within a few months of making this change, we tippled the number of packages in our Monorepo. We also saw much more work done on the linting front, leading to a more consistent codebase.</p>
<p>The linter is common to entire Monorepo, and each new rule affects all the packages.</p>
<ul>
<li><strong>config</strong> (webpack config as a package, reused by mweb and dweb)</li>
<li><strong>ui</strong> (a package to create common patterns of design to be used in mobile and desktop, thus enabling us to work on creating a Swiggy’s design system)</li>
<li><strong>payments</strong> (a package of Swiggy’s payments page, used by multiple tenants)</li>
<li><strong>reviews</strong> (a package of Swiggy’s Ratings and Reviews page and components, used by mweb and dweb)</li>
<li><strong>helpers</strong> (a package of common reusable logic, something like lodash)</li>
<li><strong>daily</strong> (swiggydaily.com, reuses 2 components from mweb)</li>
<li><strong>cache</strong> (a caching module used by mweb and dweb)</li>
<li><strong>restaurant-url</strong> (a restaurant slug generator, multiple tenants)</li>
</ul>
<p><a class="blog-image-link" href="https://bogas04.fyi/img/blog/1__kvwGrM__62LBXWLHxH__QwGw.png" target="_blank" rel="noopener noreferrer"><img src="https://bogas04.fyi/img/blog/1__kvwGrM__62LBXWLHxH__QwGw.png" alt="Image credits: undraw"></a></p>
<p>I think that giving the option to easily create a new package incentivizes developers to think in more modular terms. They don’t think in the context of an app but rather in a more general way.</p>
<p>It also discourages them from touching modules that are used by multiple tenants, and use <a href="https://semver.org/">semantic versioning</a> appropriately.</p>
<p>The benefits we are seeing out of this are just amazing:</p>
<ul>
<li>Writing the same fix for dweb and mweb is faster, as it’s just one commit.</li>
<li>No more <code>npm link</code> mess.</li>
<li>Reviewing a fix for both dweb and mweb is faster, as it’s just one Pull Request on one repository by one team member.</li>
<li>Reusing and updating build pipeline is much more seamless.</li>
<li>Updating major dependencies/lint rules is super easy.</li>
<li>The collocation of code encourages developers to copy-paste less and reuse more.</li>
<li>Writing reusable modules becomes easier, leading to better software engineering.</li>
</ul>
<h3 id="the-sadpart"><a class="heading-permalink" href="https://bogas04.fyi/blog/2019/09/monorepos-lets-talk-about-it#the-sadpart" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text">The sad&nbsp;part.</span></a></h3>
<p>But it ain’t all fun. Our PR section is a bit noisier. It’s not like we’re somehow writing more code, but that changes to any package comes to spotlight and doesn’t get silently updated.</p>
<ul>
<li>Too many packages lead to longer bootstrap times.</li>
<li>Leveraging the benefits of Monorepo takes time.</li>
<li>The code navigation is slightly slower. Developers are now opening individual packages to work around that.</li>
</ul>
<p><strong>Update:</strong> There’s one more point I would like to touch upon. Our approach currently colocates applications with libraries. ‘mweb’ is a private package in the sense it isn’t published to our npm registry, however ‘ui’ is a public package that can be consumed by mulitple tenants. This leads to heterogeneity in the monorepo. We are okay with this mix as</p>
<ul>
<li>it reduces friction of local development (no npm links).</li>
<li>colocation leads to easy refactors and library creations.</li>
<li>code review is simpler when it’s all one repository.</li>
</ul>
<h3 id="the-verdict"><a class="heading-permalink" href="https://bogas04.fyi/blog/2019/09/monorepos-lets-talk-about-it#the-verdict" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text">The verdict.</span></a></h3>
<p>So far we’re seeing Monorepo architecture a better fit for our growing codebase and team. It also impacts the way we design new libraries and components, often promoting clearer separations of concerns.</p>
<p><a class="blog-image-link" href="https://bogas04.fyi/img/blog/1__O3UIYiDjYTXMAZd7GBMwVg.png" target="_blank" rel="noopener noreferrer"><img src="https://bogas04.fyi/img/blog/1__O3UIYiDjYTXMAZd7GBMwVg.png" alt="Image credits: undraw"></a></p>
<p>Should you use monorepo? Like all things, it depends on TM! I hope this blog gave enough insight to you as to why we started using a Monorepo, and how it’s benefiting us.</p>
<blockquote>
<p>DISCLAIMER: We don’t advocate for any of the tools, libraries, coding practices or software development philosophies mentioned here. You are welcome to read, learn, accept, reject and critique however you see&nbsp;fit.</p>
</blockquote>
]]></content:encoded>
</item>

<item>
<title><![CDATA[Sharing made ridiculously easy with Web Share API]]></title>
<link>https://bogas04.fyi/blog/2017/09/sharing-made-ridiculously-easy-with-web-share-api</link>
<guid>https://bogas04.fyi/blog/2017/09/sharing-made-ridiculously-easy-with-web-share-api</guid>
<pubDate>Fri, 22 Sep 2017 16:27:20 GMT</pubDate>
<description><![CDATA[With growing mobile usage, performance and leanness (yeah, that’s a word) isbecoming top priority for web apps. Oddly enough, sharing has…]]></description>
<content:encoded><![CDATA[<p><a class="blog-image-link" href="https://bogas04.fyi/img/blog/1__qp3z0ij8v372R__DVbuJB6Q.jpeg" target="_blank" rel="noopener noreferrer"><img src="https://bogas04.fyi/img/blog/1__qp3z0ij8v372R__DVbuJB6Q.jpeg" alt="Image with icons of social media platforms"></a></p>
<blockquote>
<p>With growing mobile usage, performance and leanness (yeah, that’s a word) is becoming top priority for web apps. Oddly enough, sharing has never worked out well for web, until now (hopefully).</p>
</blockquote>
<h4 id="history-time"><a class="heading-permalink" href="https://bogas04.fyi/blog/2017/09/sharing-made-ridiculously-easy-with-web-share-api#history-time" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text">History time</span></a></h4>
<p>Since the social network explosion, ad revenue on page views and obsession with <a href="http://digg.com/">digg</a>-ing websites, social sharing “widgets” have polluted our browsing experience with numerous flaws:</p>
<p><a class="blog-image-link" href="https://bogas04.fyi/img/blog/1__rW9LubrRX5l06KUeRoCzsA.png" target="_blank" rel="noopener noreferrer"><img src="https://bogas04.fyi/img/blog/1__rW9LubrRX5l06KUeRoCzsA.png" alt=""></a></p>
<ul>
<li>They came with a dozen of JavaScript SDK files for every-single-social-network.</li>
<li>They were usually “sticky”, because that’s so cool.</li>
<li>They were hard to style, always looking pretty off from your website’s look and feel.</li>
<li>They almost always lacked one social network which was big in your region or for your audience.</li>
</ul>
<p>All these flaws became more prominent with rise of smartphones. SDKs burdened (and <a href="https://medium.freecodecamp.org/why-16-of-the-code-on-the-average-site-belongs-to-facebook-and-what-that-means-68956cd731be">still do</a>) the network and CPU, “sticky” widgets janked scrolling, and became unsurprisingly <a href="http://thinksem.com/blog/floating-social-media-share-bar-good-or-bad/">very annoying</a> at smaller resolutions (like they weren’t otherwise). And they certainly weren’t meant for everyone.</p>
<p>While solutions like lazy-loading and simpler designs helped a lot, it still is a painful job to find the right widget for your website, tweak it till the point it isn’t an eye-sore, only to find out that the users aren’t digg-ing it anymore (shameless pun-intended), and want to share it on XYZ messenger, which doesn’t have an <a href="https://faq.whatsapp.com/en/android/28000012">intent</a> URL yet.</p>
<p><a class="blog-image-link" href="https://bogas04.fyi/img/blog/1__4xpPKwDeI__BomsMMRntRTw.png" target="_blank" rel="noopener noreferrer"><img src="https://bogas04.fyi/img/blog/1__4xpPKwDeI__BomsMMRntRTw.png" alt="1990s called and it wants you to reply&nbsp;back."></a>
1990s called and it wants you to reply&nbsp;back.</p>
<p>Sadly, browsers haven’t cared enough to innovate much in this space lately. There were several attempts by Mozilla, Chrome and even <a href="http://www.lovemysurface.net/using-windows-8-share-charm-surface/">Windows 8</a>. While they still let you “email” your website on Desktop, and share to your favorite app on mobile, but that’s about it. Developer has no control over the shared title, content or the URL, which is a bigger problem when we talk about SPAs with fancy URLs.</p>
<h4 id="tldr"><a class="heading-permalink" href="https://bogas04.fyi/blog/2017/09/sharing-made-ridiculously-easy-with-web-share-api#tldr" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text">tl;dr</span></a></h4>
<p>And this changes with <a href="https://developers.google.com/web/updates/2016/09/navigator-share">Web Share API</a>. Wow, that’s quite a lot of build up for a simple API, isn’t it&nbsp;? But this API is remarkable&nbsp;!</p>
<p>And that’s it&nbsp;! In order to use it, you need to meet following conditions though:</p>
<blockquote>
<p>Your site must be served over <a href="https://www.chromium.org/Home/chromium-security/prefer-secure-origins-for-powerful-new-features">HTTPS</a>.</p>
</blockquote>
<blockquote>
<p>You can only invoke the API in response to a user action, such as a click (e.g., you can’t call <code>navigator.share</code> as part of the page load).</p>
</blockquote>
<blockquote>
<p>You can also share any URL, not just URLs under your website’s current scope: and you may also share <code>text</code> without a URL.</p>
</blockquote>
<blockquote>
<p>You should feature-detect it in case it’s not available on your users’ platform (e.g., via <code>'share' in navigator</code>)</p>
</blockquote>
<p>The API is still a proposal, however it’s implemented in Chrome 61, which is the latest stable version at time of writing. Which means, in next 6 weeks, this API would be available on almost every other Android phone. If you’re still not sold and think intents are the way to go, you can head over to the <a href="https://github.com/WICG/web-share/blob/master/docs/explainer.md#frequently-asked-questions">FAQ</a> section of the proposal to learn about some decent arguments.</p>
<p>The <a href="http://mobile.twitter.com/">awesome PWA</a> of <a href="https://medium.com/@paularmstrong/twitter-lite-and-high-performance-react-progressive-web-apps-at-scale-d28a00e780a3">Twitter</a> already uses <a class="blog-image-link" href="https://bogas04.fyi/img/blog/1__tGS6QdpXiL7m21oPm25v7A.png" target="_blank" rel="noopener noreferrer"><img src="https://bogas04.fyi/img/blog/1__tGS6QdpXiL7m21oPm25v7A.png" alt="Web Share API for sharing&nbsp;tweets."></a></p>
<h4 id="future"><a class="heading-permalink" href="https://bogas04.fyi/blog/2017/09/sharing-made-ridiculously-easy-with-web-share-api#future" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text">Future</span></a></h4>
<p>Did I say that’s it? Because that isn’t it yet.</p>
<ul>
<li>The share data (title, url and text presently) isn’t just limited to current set. There <a href="https://wicg.github.io/web-share/#extensibility-of-this-api">would</a> be additions to it in future, <code>image</code> being one for example.</li>
<li>There’s a sibling API, <a href="https://github.com/mgiuca/web-share-target">Web Share Target</a>, which allows a <a href="https://developers.google.com/web/progressive-web-apps/">PWA</a> to be listed in the native app share drawer. This brings web apps way closer to the native experience. Learn more about that proposal <a href="https://github.com/mgiuca/web-share-target/blob/master/docs/explainer.md">here</a>.</li>
</ul>
<h4 id="contribute"><a class="heading-permalink" href="https://bogas04.fyi/blog/2017/09/sharing-made-ridiculously-easy-with-web-share-api#contribute" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text">Contribute</span></a></h4>
<p>So start adding support to this awesome API right now, and if you would like to have this API well supported please follow/vote/share/contribute to the bug numbers I’m listing below;</p>
<ul>
<li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1402369">Firefox Bug 1402369</a></li>
<li><a href="https://bugs.webkit.org/show_bug.cgi?id=171100">Webkit Bug 171100</a></li>
<li><a href="https://wpdev.uservoice.com/forums/257854-microsoft-edge-developer/suggestions/31563175-implement-web-share-api">Edge User Voice</a></li>
</ul>
]]></content:encoded>
</item>

<item>
<title><![CDATA[My 15 kg weight loss journey]]></title>
<link>https://bogas04.fyi/blog/2017/07/my-15-kg-weight-loss-journey</link>
<guid>https://bogas04.fyi/blog/2017/07/my-15-kg-weight-loss-journey</guid>
<pubDate>Thu, 20 Jul 2017 10:31:03 GMT</pubDate>
<description><![CDATA[So coming to my story, I didn’t quite intend to lose weight, or follow anydiet, or did a rigorous workout. I believe that it’s basically…]]></description>
<content:encoded><![CDATA[<p><a class="blog-image-link" href="https://bogas04.fyi/img/blog/1__AW6KCuaBBSUSWKu8dIrmLA.png" target="_blank" rel="noopener noreferrer"><img src="https://bogas04.fyi/img/blog/1__AW6KCuaBBSUSWKu8dIrmLA.png" alt="A picture showing downward trend of my body weight from 90kg to 69kg over few months"></a></p>
<p>So coming to my story, I didn’t quite intend to lose weight, or follow any diet, or did a rigorous workout. I believe that it’s basically the result of negative-feedback in my brain. Sounds weird right? I’ll explain.</p>
<h3 id="before"><a class="heading-permalink" href="https://bogas04.fyi/blog/2017/07/my-15-kg-weight-loss-journey#before" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text">Before</span></a></h3>
<p>I’ll first go through initial state variables;</p>
<ul>
<li>Age: 22 years and 9 months</li>
<li>Weight: 87 kilograms | 191 pounds</li>
<li>Height: 174 centimeters | 5 feet 8.5 inches</li>
<li>Waist: 91 centimeters | 36 inches</li>
<li><a href="https://www.nhlbi.nih.gov/health/educational/lose_wt/BMI/bmi-m.htm">BMI</a>: 28.7 (Overweight, 4 kilograms from being obese)</li>
<li><a href="https://www.health-calc.com/body-composition/waist-to-height-ratio">Waist to Height</a>: 0.52 (Males at increased risk)</li>
<li>Vegetarian? ✔</li>
<li>Very low sugar intake? ✔</li>
<li>Significant workout throughout the day? ✗</li>
</ul>
<p>Depending on where you come from, this might not look bad enough, and which was the exact attitude that kept me from doing anything significant about it (and I never did!). I tried the gym, but I always felt it wasn’t quite a sustainable solution, I wanted something that I could do in my daily routine.</p>
<p>It’s like, you can starve for 2 months and lose plenty, but that one day when you decide to eat something good, you just lose your control. Similarly, you might work out well for 2 months, but a long vacation to grandma’s might be enough to make you lousy again. These are very fragile methods in my opinion, for my sort of lifestyle in which work, commute, <em>*cough* Netflix</em> take most of the time.</p>
<h3 id="the-change"><a class="heading-permalink" href="https://bogas04.fyi/blog/2017/07/my-15-kg-weight-loss-journey#the-change" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text">The Change</span></a></h3>
<p>So what started the chain of events was this app called <a href="https://play.google.com/store/apps/details?id=com.google.android.apps.fitness">Google Fit</a>. It’s a basic fitness app that uses your phone sensors to calculate steps/calories burnt/distance covered. That’s pretty much it.</p>
<p><a class="blog-image-link" href="https://bogas04.fyi/img/blog/1__WFkALvcY68HD__PaoixgiiQ.png" target="_blank" rel="noopener noreferrer"><img src="https://bogas04.fyi/img/blog/1__WFkALvcY68HD__PaoixgiiQ.png" alt="23rd of February is when I installed the app, though it took 3 days to get me to work on my&nbsp;goal."></a>
23rd of February is when I installed the app, though it took 3 days to get me to work on my&nbsp;goal.</p>
<p>Annnnd I forgot about it for three days. I opened it one day to see that I actually completed the goal of 10,000 steps on a Saturday when I went for a walk by the lake. That was easy! What I also observed was that I roughly burnt 1,700 ~ 2,000 calories by doing nothing throughout the day. Even if the data isn’t accurate, the sensor and environment conditions remain the same, making it a reliable way to observe variations and not the absolute values.</p>
<p>My brain was intrigued by these numbers. It’s almost how you add hashtags to Instagram posts to get more likes, and once you do get more, you overdo it, and the cycle continues. Just that, here you get likes from health!</p>
<p><a class="blog-image-link" href="https://bogas04.fyi/img/blog/1__EmZytUAuspI__mycZ__o9OGw.png" target="_blank" rel="noopener noreferrer"><img src="https://bogas04.fyi/img/blog/1__EmZytUAuspI__mycZ__o9OGw.png" alt="VERY TECHNICAL. MUCH&nbsp;SCIENCE."></a>
VERY TECHNICAL. MUCH&nbsp;SCIENCE.</p>
<p>So the first thing I did was that I <em>reduced the goal to 9,000 steps</em> to make myself feel better. And every week I increased it by 500–1000 steps as and when I started getting a good rhythm.</p>
<p>The other thing that I did was that I took interest in knowing calories of things I ate daily. By learning that a spoon of oil has as many calories as a bowl of corn flakes, which in turn has as many calories as a can of cola, I somehow started making food at home to avoid the extra cheese/butter/oil the chefs put in.</p>
<p><a class="blog-image-link" href="https://bogas04.fyi/img/blog/1__UFCQ__sve25zCXqzQc__rYxA.png" target="_blank" rel="noopener noreferrer"><img src="https://bogas04.fyi/img/blog/1__UFCQ__sve25zCXqzQc__rYxA.png" alt="Remember, one is a breakfast, one is a drink with a snack, and other is added to your lunch just like&nbsp;that!"></a>
Remember, one is a breakfast, one is a drink with a snack, and other is added to your lunch just like&nbsp;that!</p>
<p>Again, didn’t intend to, it’s just my brain trying to optimize calorie intake.</p>
<p>Not only I became more aware of the calories that I put it, I also started reducing them by simply cooking at home with better alternatives.</p>
<p>This number was insightful in an indirect way. Knowing that I was burning say 2000 calories daily, by ensuring low-calorie diet (without compromises), and burning more than the usual 2000, there was no way for me to not lose weight. And I did.</p>
<p><a class="blog-image-link" href="https://bogas04.fyi/img/blog/1__7emoMCCIFij0dncEASB94g.gif" target="_blank" rel="noopener noreferrer"><img src="https://bogas04.fyi/img/blog/1__7emoMCCIFij0dncEASB94g.gif" alt="MILLIONS OF&nbsp;CALORIES"></a>
MILLIONS OF&nbsp;CALORIES</p>
<p>Losing weight is really no rocket-science. Either take in lesser calories or burn more than you eat or BOTH!</p>
<p>Adding to these two numbers, I also bought a nice digital weighing scale, only to get depressed every morning, which again helped me complete those extra 500 steps or choose fruits overs chips for snacks.</p>
<p>So to summarize, all I did was;</p>
<ul>
<li>Ensure I complete my steps daily, and increase them ever-so-slightly every week. I stopped increasing beyond 15,000 steps though.</li>
<li>Count calories of random food that I regularly ate, and replaced with better non-processed alternatives.</li>
<li>Eat out less often.</li>
<li>Check my weight regularly. The more aware I became of how previous day’s activity resulted in lower weight, the more my brain took it as a reward and probably released <a href="https://en.wikipedia.org/wiki/Oxytocin">Oxytocin</a> to give a sense of contentment and incompleteness at the same time. Negative feedback.</li>
</ul>
<h3 id="the-results"><a class="heading-permalink" href="https://bogas04.fyi/blog/2017/07/my-15-kg-weight-loss-journey#the-results" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text">The Results</span></a></h3>
<p><a class="blog-image-link" href="https://bogas04.fyi/img/blog/1__OHlYFf__A8U689ORGveNMHA.png" target="_blank" rel="noopener noreferrer"><img src="https://bogas04.fyi/img/blog/1__OHlYFf__A8U689ORGveNMHA.png" alt="Downward trend of weight"></a></p>
<ul>
<li>Age: 23 years and 1 month</li>
<li>Weight: 72 kilograms | 158.7 pounds</li>
<li>Height: 174 centimeters | 5 feet 8.5 inches</li>
<li>Waist: 84 centimeters | 33 inches</li>
<li><a href="https://www.nhlbi.nih.gov/health/educational/lose_wt/BMI/bmi-m.htm">BMI</a>: 23.8 (Normal weight, 4 kilograms from being overweight)</li>
<li><a href="https://www.health-calc.com/body-composition/waist-to-height-ratio">Waist to Height</a>: 0.48 (OK)</li>
<li>Pseudo-Vegan? ✔</li>
<li>Very low sugar intake? ✔</li>
<li>Significant workout throughout the day? ✔</li>
</ul>
<h3 id="conclusion"><a class="heading-permalink" href="https://bogas04.fyi/blog/2017/07/my-15-kg-weight-loss-journey#conclusion" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text">Conclusion</span></a></h3>
<p>I basically lost roughly 1 kilogram a week. At the same time I also went to grandma’s house (= fat rich food), ate out and ate heavy items (= too many calories), and even fall ill (= very little walk). I simply increased my steps for those days or did extra steps later. Basically, I didn’t change my lifestyle at all, apart from dedicating 2–3 hours to walk and cooking daily.</p>
<p><a class="blog-image-link" href="https://bogas04.fyi/img/blog/1__B3QKpZdPXxmFaDsc9XQbdg.png" target="_blank" rel="noopener noreferrer"><img src="https://bogas04.fyi/img/blog/1__B3QKpZdPXxmFaDsc9XQbdg.png" alt="I meet my goals daily, and compensate whenever I eat&nbsp;outside."></a>
I meet my goals daily, and compensate whenever I eat&nbsp;outside.</p>
<p>So by minor changes in my lifestyle, I found myself becoming less lethargic, which only helped me improve it more and more. I could work for long hours, walk for 2 hours, then cook food and still feel active!</p>
<p>Over time, I also found myself leaning towards a vegan diet. Watching <a href="http://www.cowspiracy.com/">Cowspiracy</a> and <a href="http://www.whatthehealthfilm.com/">What the Health</a> helped me with it greatly. I still have milk in coffee (creamer as it’s called in the west) &amp; ice creams on some days though. Still working on it. YouTube Channels like <a href="https://www.youtube.com/user/rawvegannotgross">Raw. Vegan. Not Gross</a> &amp; <a href="https://www.youtube.com/channel/UCEjkioV3LO_OIUaSWRxFZ3A">Cheap Lazy Vegan</a> help me a lot with non-dairy experiments. It’s simply unavailability of vegan alternatives in India that make me lose to coffee creamer.</p>
<p>Some clarifications I want to make here;</p>
<ul>
<li>I didn’t starve. I just ate better alternatives. I still had plenty of cheat days, but with reduced quantities and compensation for same.</li>
<li>I didn’t exhaust myself. Walking is the most basic exercise which is good for general health and doesn’t quite focus on any one body part. I lost weight not only from my calves &amp; thighs, but also from my face, arms, and waist. I also did push-ups to ensure muscle growth in torso region.</li>
<li>Girls are still not interested in me. Sigh.</li>
<li>Men on other hand compliment, saying I’ve become leaner. PROFIT???</li>
</ul>
<p>As always, it worked for me, but might not work for you. However, I’ve seen people reduce weight just by, say, getting rid of sugar, or meat, or dairy. In my case, these were already pretty much absent. Apparently, dieting wasn’t enough to pull this off alone, which is why I believe basic exercise like walking together with a better diet helped me overall. My advice would be to not look at long term gains, but to compare between days and weeks.</p>
<p>My quest is still on. I intend to sit in the middle of the ideal BMI range, and also improve on my Vegan skills.</p>
<p>Here’s a before (Feb 2017, 87kg | 192lb) &amp; after (Oct 2017, 69kg | 152 lb) picture.</p>
<blockquote>
<p><strong>Update Nov 2017:</strong> I lost even more weight since the time I posted this blog, about 3–4 kgs (6.6–8.8 lbs). And I also turned full vegan.</p>
</blockquote>
<p>PS:</p>
<ul>
<li>BMI and other such metrics have flaws. Don’t be too serious about them.</li>
<li>Losing weight doesn’t always mean better health. Consult a dietitian or whatever.</li>
<li>Feel free to analyze my case &amp; give remarks.</li>
</ul>
]]></content:encoded>
</item>

<item>
<title><![CDATA[Release of Samsung Internet Chrome Extension v2]]></title>
<link>https://bogas04.fyi/blog/2017/03/release-of-samsung-internet-chrome-extension-v2</link>
<guid>https://bogas04.fyi/blog/2017/03/release-of-samsung-internet-chrome-extension-v2</guid>
<pubDate>Thu, 09 Mar 2017 06:02:13 GMT</pubDate>
<description><![CDATA[]]></description>
<content:encoded><![CDATA[<blockquote>
<p><strong>Update Oct 2017:</strong> Since the release of v2 (March 2017), we saw a <strong>9.3x increase</strong> in our monthly active users (~8k to 75k). We also observed <strong>35% jump</strong> in the rating. Thank you so much for using &amp; liking our extension, stay tuned for more updates!</p>
</blockquote>
<p><a class="blog-image-link" href="https://bogas04.fyi/img/blog/1__e16MS4BgBe8e__DtlF666JA.png" target="_blank" rel="noopener noreferrer"><img src="https://bogas04.fyi/img/blog/1__e16MS4BgBe8e__DtlF666JA.png" alt=""></a></p>
<p>Today we are very glad to release the much awaited <a href="https://chrome.google.com/webstore/detail/samsung-internet/epejdmjgfibjaffbmojllapapjejipkh">version 2</a> of our Chrome Extension. <a href="https://chrome.google.com/webstore/detail/samsung-internet/epejdmjgfibjaffbmojllapapjejipkh">Install</a> it today to sync bookmarks across your Chrome browser on PC and Samsung Internet.</p>
<p>The Samsung Internet extension, earlier known as Samsung Sync (v1.4), not only sports a new name but also comes with tonnes of features and a massive UI overhaul. I’ll walk-through the new additions in the article.</p>
<blockquote>
<p>Drastic improvements to first-sync performance.</p>
</blockquote>
<p>First-sync performance was the number one complaint in our web store reviews, usually leaving users to never actually getting around to use our extension. We hit the heart of the issue with a dagger by rewriting several modules and chaining network requests, database queries and DOM updates in a much more optimized manner. With this release, you can now not only see the progress of sync, but also the fetched bookmarks as and when they arrive. We feel this will solve the top complaint and allow users to enjoy the extension.</p>
<p><a class="blog-image-link" href="https://bogas04.fyi/img/blog/1__qYPi94TVyTF1p1aX1BCW9g.gif" target="_blank" rel="noopener noreferrer"><img src="https://bogas04.fyi/img/blog/1__qYPi94TVyTF1p1aX1BCW9g.gif" alt=""></a></p>
<blockquote>
<p>Consistent UI with <a href="https://play.google.com/store/apps/details?id=com.sec.android.app.sbrowser">Samsung Internet on&nbsp;Android.</a></p>
</blockquote>
<p>We are proud of our UX team’s efforts in offering a very modern look and feel to the extension. The small 600 x 400 screen real estate makes it much harder to add features while keeping the interface user-friendly. After several iterations, I think we’ve pretty much nailed it. From a progress bar to show sync status to modals for bookmark management, the UI even though offering several functionalities doesn’t overwhelm the user.</p>
<p><a class="blog-image-link" href="https://bogas04.fyi/img/blog/1__hE8PGhNMYIhyt3WsuEF50Q.png" target="_blank" rel="noopener noreferrer"><img src="https://bogas04.fyi/img/blog/1__hE8PGhNMYIhyt3WsuEF50Q.png" alt="Live loading of bookmarks, top requested feature."></a>
Live loading of bookmarks, top requested feature.</p>
<blockquote>
<p>Enhanced bookmark management.</p>
</blockquote>
<p>The previous version (1.4) was bit limiting in the sense users could only edit title or delete a bookmark. We felt that the extension can offer much more than that and with today’s release, not only basic create / update / delete / move is supported, but users can also import Chrome bookmarks into their Samsung account. We feel that this brings the control back to the user.</p>
<p><a class="blog-image-link" href="https://bogas04.fyi/img/blog/1__d6bWg__Yhi2DyDM0JSZdrjA.png" target="_blank" rel="noopener noreferrer"><img src="https://bogas04.fyi/img/blog/1__d6bWg__Yhi2DyDM0JSZdrjA.png" alt="Improved Bookmark Management"></a>
Improved Bookmark Management</p>
<blockquote>
<p>And much&nbsp;more…</p>
</blockquote>
<p>The feature list just doesn’t stop here&nbsp;! Some of the other miscellaneous changes:</p>
<ul>
<li>Context menu support to bookmark current tab with a single click.<br>
<em>Pro tip: You can use</em> <strong><em>Ctrl/Cmd + Shift + Y</em></strong> <em>combination to bookmark instantly.</em></li>
<li>Improved internationalization for supported languages.</li>
<li>Improved keyboard accessibility, you can tab your way through all items.</li>
</ul>
<blockquote>
<p><strong>Update April 2017:</strong> Version 2.0.5 is now released to Chrome Web Store that fixes login related issues faced by certain users with the previous version (2.0.3).</p>
</blockquote>
<p>Let us know if you run into issues, or just want to give us some feedback. We’ll follow up soon with our plans for releasing the extension for other browsers. Make sure you follow <a href="https://medium.com/samsung-internet-dev">Samsung Internet Developers</a> on <a href="https://twitter.com/samsunginternet">twitter</a>.</p>
<p><strong>Note:</strong> The Sync functionality is only available for phones logged in with a Samsung Account on a stable release of Samsung Internet, which means that it won’t work with <a href="https://medium.com/samsung-internet-dev/samsung-internet-beta-now-available-without-sign-up-e0d5d4010838#.ntaxejovf">Samsung Internet Beta</a> (v5.4) on non-samsung phones, just yet.</p>
]]></content:encoded>
</item>

<item>
<title><![CDATA[Living in Suwon, Korea]]></title>
<link>https://bogas04.fyi/blog/2016/11/living-in-suwon-korea</link>
<guid>https://bogas04.fyi/blog/2016/11/living-in-suwon-korea</guid>
<pubDate>Sun, 27 Nov 2016 11:48:44 GMT</pubDate>
<description><![CDATA[First of all, let me clear out that I’m not a blogger, and definitely not asequipped in English as I would say I’m in JavaScript.]]></description>
<content:encoded><![CDATA[<p>First of all, let me clear out that I’m not a blogger, and definitely not as equipped in English as I would say I’m in JavaScript. Now that’s been established, let’s talk about me, Samsung and Suwon.</p>
<p><a class="blog-image-link" href="https://bogas04.fyi/img/blog/south-korea-xmas.jpg" target="_blank" rel="noopener noreferrer"><img src="https://bogas04.fyi/img/blog/south-korea-xmas.jpg" alt="Christmas celebrations in Seoul, South Korea"></a></p>
<h3 id="me"><a class="heading-permalink" href="https://bogas04.fyi/blog/2016/11/living-in-suwon-korea#me" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text">Me</span></a></h3>
<p>A Sikh Male rocking sick beard with a Punjabi Turban, and Orange Gaatra that holds a long&nbsp;<a href="https://en.wikipedia.org/wiki/Kirpan">Kirpan</a>.</p>
<p><a class="blog-image-link" href="https://bogas04.fyi/img/blog/1__sCPawDEOQs9dTX5wPN4e__A.jpeg" target="_blank" rel="noopener noreferrer"><img src="https://bogas04.fyi/img/blog/1__sCPawDEOQs9dTX5wPN4e__A.jpeg" alt="A Sikh Male rocking sick beard with a Punjabi Turban, and Orange Gaatra that holds a long&nbsp;Kirpan"></a></p>
<p>I’m a <a href="http://www.sikhiwiki.org/index.php/Main_Page">Sikh</a> male who graduated from <a href="http://nsit.ac.in/">NSIT</a>, <a href="https://en.wikipedia.org/wiki/New_Delhi">New Delhi</a> in Computer Engineering discipline in 2016. Before starting off my engineering career, I’d developed horrible Visual Basic applications and knew exactly what I wanted to do in my life; create <a href="https://www.youtube.com/watch?v=d5LzH2sh1rk">stupid</a> UIs with no knowledge of design. After joining the college, I made a very sane unintentional decision of learning JavaScript to make websites/webapps. Back then, JavaScript wasn’t even looked upon as a serious language, NodeJS was in its baby years of popularity, and using jQuery was cool. But I don’t know why, I kept coding in it. And this very thing and some luck landed me up in a summer internship at Samsung R&amp;D Institute, Bangalore where I worked on a NodeJS project. And that lead me to,,, wait, I need to start a Samsung heading.</p>
<h3 id="samsung"><a class="heading-permalink" href="https://bogas04.fyi/blog/2016/11/living-in-suwon-korea#samsung" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text">Samsung</span></a></h3>
<p><a class="blog-image-link" href="https://bogas04.fyi/img/blog/1____g5l9BybNJiUO22dNPEeYg.jpeg" target="_blank" rel="noopener noreferrer"><img src="https://bogas04.fyi/img/blog/1____g5l9BybNJiUO22dNPEeYg.jpeg" alt="Samsung Digital City,&nbsp;Suwon"></a>
Samsung Digital City,&nbsp;Suwon</p>
<p>Yeah, so that lead me to a full time job at SRIB, which again lead me to Suwon, the place where HQ of Samsung Electronics resides. I’m part of Web Team in SRIB, that is also responsible for <a href="https://medium.com/samsung-internet-dev">Samsung Internet</a>, and I am currently overhauling the <a href="https://chrome.google.com/webstore/detail/samsung-sync/epejdmjgfibjaffbmojllapapjejipkh?hl=en">Samsung Sync extension</a>. Expect a major update soon!</p>
<p>It’s funny how the ship of JavaScript sailed me across from one island to another. And now, I’m typing this from Suwon as my last week of business trip is about to start.</p>
<p>I love the wide range of technologies that exist within Samsung Electronics. This provides a great canvas for freshers to try and experiment with all domains without having to switch jobs.</p>
<h3 id="korea"><a class="heading-permalink" href="https://bogas04.fyi/blog/2016/11/living-in-suwon-korea#korea" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text">Korea</span></a></h3>
<p>This last week has brought several memories of this 2 month stay in Korea, which in turn encouraged me to write this post on a Sunday evening.</p>
<p><a class="blog-image-link" href="https://bogas04.fyi/img/blog/1__ng__tz1ZRfUcuEaSPWdKFdQ.jpeg" target="_blank" rel="noopener noreferrer"><img src="https://bogas04.fyi/img/blog/1__ng__tz1ZRfUcuEaSPWdKFdQ.jpeg" alt="Somewhere in&nbsp;Suwon"></a>
Somewhere in&nbsp;Suwon</p>
<p>The country is amazing, it’s a developed nation, which is a thing a citizen of a developing nation would observe first. The racial and social security is really great here, in contrast to west where <a href="https://en.wikipedia.org/wiki/Islamophobia">Islamophobia</a> is a big deal. And the people are really humble. I love how everyone greets you and bows down a little, they take out time to wish you well, and that’s heart warming for a foreigner.</p>
<p><a class="blog-image-link" href="https://bogas04.fyi/img/blog/1__qDzv5NoBmcDetWPiftOj__A.jpeg" target="_blank" rel="noopener noreferrer"><img src="https://bogas04.fyi/img/blog/1__qDzv5NoBmcDetWPiftOj__A.jpeg" alt="Hotel staff at DreamVill"></a>
Hotel staff at DreamVill</p>
<p>I was lucky enough to witness both falls; fall fall and first snowfall, former being a phenomenon that doesn’t really exist in India.</p>
<p><a class="blog-image-link" href="https://bogas04.fyi/img/blog/1__KvkZ__uwm7oa3ENgorLT5ug.jpeg" target="_blank" rel="noopener noreferrer"><img src="https://bogas04.fyi/img/blog/1__KvkZ__uwm7oa3ENgorLT5ug.jpeg" alt=""></a>
<a class="blog-image-link" href="https://bogas04.fyi/img/blog/1__BrdQH1cUwbrbO6MO7QF__aQ.jpeg" target="_blank" rel="noopener noreferrer"><img src="https://bogas04.fyi/img/blog/1__BrdQH1cUwbrbO6MO7QF__aQ.jpeg" alt="Fall Leaves"></a>
Fall Leaves</p>
<p><a class="blog-image-link" href="https://bogas04.fyi/img/blog/1__zRKNo__JVjQFn2EOCwQ1QNA.gif" target="_blank" rel="noopener noreferrer"><img src="https://bogas04.fyi/img/blog/1__zRKNo__JVjQFn2EOCwQ1QNA.gif" alt="Snow Falls"></a>
Snow Falls</p>
<p>However, as a vegetarian I found myself at great discomfort in finding food outside DreamVill that serves Indian cuisine. So for vegetarian/vegan visitors, please bring some packaged food if you’re planning a long visit.</p>
<p><a href="https://www.google.co.kr/maps/place/Hwaseong+Fortress/@37.2807935,127.0102456,15z/data=!4m2!3m1!1s0x0:0x809c61d30ab56214?sa=X&amp;ved=0ahUKEwipktCA7sjQAhWFybwKHUA4B8QQ_BIIgwEwDg">Hwaseong Fortress</a>]</p>
<p><a href="https://bogas04.fyi/img/blog/1__RDHDZhOnDTUKypNH__vp1wQ.jpeg">Imagee of Hwaseong Fortress</a></p>
<p>Some places like <a href="https://www.google.com/maps/place/%ED%8C%8C%EB%A6%AC%EB%B0%94%EA%B2%8C%EB%9C%A8+%EC%98%81%ED%86%B5%EB%89%B4%EC%9B%94%EB%93%9C%EC%A0%90/@37.2536243,127.0674148,15z/data=!4m8!1m2!2m1!1sparis+baguette!3m4!1s0x0:0x794b659d3dad89b8!8m2!3d37.2520187!4d127.0710522?hl=en">Paris Baguette</a>, <a href="https://www.google.com/maps/place/%EB%9A%9C%EB%A0%88%EC%A5%AC%EB%A5%B4/@37.2536913,127.0674148,15z/data=!4m8!1m2!2m1!1sTous+Les+Jours!3m4!1s0x357b44c4c1f2a6bd:0xb1aff268e48c54e2!8m2!3d37.2520193!4d127.0709693?hl=en">Tous Les Jours</a> etc. are good to look for vegan/vegetarian bread or salad sandwiches. If you’re lucky enough, you can find meat-free salads at bakeries and eateries of the like however.</p>
<p><a class="blog-image-link" href="https://bogas04.fyi/img/blog/1__axarHRa8ZbcIwJwJr2xGoA.jpeg" target="_blank" rel="noopener noreferrer"><img src="https://bogas04.fyi/img/blog/1__axarHRa8ZbcIwJwJr2xGoA.jpeg" alt="Early Christmas Decorations in&nbsp;Seoul"></a>
Early Christmas Decorations in&nbsp;Seoul</p>
<p>There are various tourist places that you can visit, though I primarily remained near the city. As a Sikh, it was pleasant surprise to find a <a href="https://en.wikipedia.org/wiki/Gurdwara">Gurdwara</a> in the country however. Run by primarily the <a href="https://en.wikipedia.org/wiki/Punjabis">Punjabi</a> community, the Gurdwara is well maintained and open to all. I visited it during lunch time and it was lovely to find everyone enjoying <a href="https://en.wikipedia.org/wiki/Langar_%28Sikhism%29">Langar</a> together on a Sunday noon.</p>
<p><a class="blog-image-link" href="https://bogas04.fyi/img/blog/1__x9oZ2fWNHKVWgEap__5YoCA.jpeg" target="_blank" rel="noopener noreferrer"><img src="https://bogas04.fyi/img/blog/1__x9oZ2fWNHKVWgEap__5YoCA.jpeg" alt="Image of Gurdwara"></a>
<a href="https://www.google.co.kr/maps/place/Gurudwara+Shri+Singh+Sabha/@37.8185614,127.1303603,15z/data=!4m2!3m1!1s0x0:0x7b23842b65fbbbd4?sa=X&amp;ved=0ahUKEwjH0eHk7MjQAhVRNrwKHfTaBL8Q_BIIggEwCg">Gurdwara Shri Singh Sabha&nbsp;Sahib</a></p>
<h3 id="closing-note"><a class="heading-permalink" href="https://bogas04.fyi/blog/2016/11/living-in-suwon-korea#closing-note" tabindex="0"><span class="heading-permalink-icon" aria-hidden="true">🔗</span><span class="heading-permalink-text">Closing Note</span></a></h3>
<p>So as I begin packing for my return flight to India, I wish to thank every Korean that has helped me find my way and replied with an <a href="http://www.123rf.com/photo_8638384_serious-and-determined-young-man-makes-an-x-shape-with-his-arms-and-hands-this-could-mean-stop-cross.html">arm cross</a> to my search of vegetarian food. Your country is amazing, and I definitely wish to visit it again, hopefully after learning Korean. Gamsahamnida&nbsp;:)</p>
<p>Stick around to see more random blog posts from this idiot.</p>
]]></content:encoded>
</item>
</channel>
</rss>
