<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Anis 💌 React20Bulletin on Medium]]></title>
        <description><![CDATA[Stories by Anis 💌 React20Bulletin on Medium]]></description>
        <link>https://medium.com/@anisurrahmanbup?source=rss-d463021d2ee9------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*PbQ7E0q7TiaIHbRNCJ0jBw.jpeg</url>
            <title>Stories by Anis 💌 React20Bulletin on Medium</title>
            <link>https://medium.com/@anisurrahmanbup?source=rss-d463021d2ee9------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sat, 30 May 2026 09:19:03 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@anisurrahmanbup/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[You Spend Half Your Time Fixing Things: 6 Surprising Lessons from Software Debugging]]></title>
            <link>https://medium.com/@anisurrahmanbup/you-spend-half-your-time-fixing-things-6-surprising-lessons-from-software-debugging-7c8a06d18f16?source=rss-d463021d2ee9------2</link>
            <guid isPermaLink="false">https://medium.com/p/7c8a06d18f16</guid>
            <dc:creator><![CDATA[Anis  React20Bulletin]]></dc:creator>
            <pubDate>Wed, 14 Jan 2026 19:55:05 GMT</pubDate>
            <atom:updated>2026-01-14T19:55:05.807Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*5qTV990Xdv0Y-OxCPpSk1Q.png" /><figcaption>Debugging, fixing error, <strong>bug, </strong>Debugging hacks, ai, AI-Powered Debugging</figcaption></figure><blockquote><strong>You’ve been writing code for hours. Everything looks clean, logical, and perfect. You click the ‘Run’ button, and in an instant, your screen floods with red text — an error. It’s hard to find a person who hasn’t experienced such a situation.</strong></blockquote><h3>1. You Spend 50% of Your Time Debugging — and That’s Normal</h3><blockquote>If you feel like a “<strong>failed programmer</strong>” after spending hours chasing down a single bug, you need to know this: you are not alone.</blockquote><h4><strong>Did you know?</strong></h4><blockquote><strong>A 2022 study by the University of Cambridge found that developers spend about 50% of their coding time debugging and fixing errors.</strong></blockquote><p>Debugging and fixing errors isn’t wasted effort — <strong>it’s real learning</strong>. Even experienced coders spend a huge portion of their time debugging.</p><p><strong>Each time you fix a bug or resolve an error,</strong> <em>you become better at writing clean code and spotting problems faster.</em></p><h3>2. The Golden Rule of Debugging: Don’t Panic</h3><blockquote>The first and most important rule of debugging is simple: <strong>Don’t Panic</strong>.</blockquote><p>When our code breaks, our brain has a tendency to shut down in the face of what looks like chaos.</p><p>But the reality is that almost all bugs are fixable, and most of them stem from tiny, overlooked mistakes.</p><p>You might be surprised to learn that many complex-looking problems are caused by something as simple as a “<strong><em>misspelled word or a missing bracket</em></strong>.”</p><h3>3. Make the Invisible Visible</h3><blockquote>When a bug isn’t obvious from just reading the code, you need to make the execution process visible.</blockquote><p>Simple commands like <strong><em>print()</em></strong> in Python or <strong><em>console.log()</em></strong> in JavaScript work like magic. By placing them strategically, you can check the values of variables at different points and confirm whether specific parts of your code are even being reached.</p><p>When the logic errors run deeper, it’s time to use a debugger.</p><p>A debugger is a powerful tool that lets you run your program step by step, setting “breakpoints” to pause execution and inspect everything that’s happening.</p><h4>Never see bugs or errors as failures.</h4><p>🔹 <em>Read error messages carefully</em></p><p>🔹 <em>Check brackets, spelling &amp; punctuation</em></p><p>🔹 <em>Use </em><strong><em>print() / console.log()</em></strong><em> to trace variables</em></p><p>🔹 <em>Debug step by step with breakpoints</em></p><p>🔹 <em>Copy error messages into Google or Stack Overflow. Someone’s already solved your exact problem.</em></p><h3>4. Be Systematic, Then Step Away</h3><blockquote><strong>Debugging is not just a technique; it’s a disciplined habit.</strong></blockquote><p>In a rush to find a solution, many of us make multiple changes at once. This is a critical mistake. A core principle of effective debugging is to make only one change at a time, then test. If you change too much, you’ll never know what fixed the problem — or what made it worse.</p><p>And what about when nothing seems to work? When you’ve been staring at the screen for hours and your head is spinning, the best strategy is often the most counter-intuitive: <strong><em>step away for five minutes. Take a short walk, sip some tea, or just look out the window. This mental break gives your tired brain a pair of “fresh eyes” that can often spot the obvious mistake you were missing before.</em></strong></p><h3>5. Talk It Out (Even to a Duck)</h3><p>Sometimes the solution is not in the code, but in the act of explaining it.</p><p>The most surprisingly effective expert technique is known as <strong>‘rubber duck debugging.’</strong></p><p>The process is simple: you explain your code and the bug you’re facing, line by line, to a solid object like a rubber duck on your desk.</p><p>The act of expressing the problem out loud forces you to organize your thoughts and assumptions, making the solution become obvious.</p><h3>6. AI-Powered Debugging</h3><p><strong><em>AI Is Here to Make Debugging Less Painful, Not to Replace You:</em></strong></p><p>We are living in a new era for debugging, thanks to the rise of Artificial Intelligence. AI-powered tools can analyze your code, identify potential bugs, and suggest solutions, reducing hours of manual work to just minutes.</p><p>Tools like <a href="https://snyk.io/platform/">Snyk Code AI</a> don’t just find errors; they also recommend ways to make your code safer and more efficient.</p><blockquote>A common fear among developers is that these tools will eventually make their roles obsolete. The answer is a clear “No.” AI tools are designed to assist you, not replace you.</blockquote><h3>At the end:</h3><blockquote>Debugging should never be seen as a sign of defeat. It is a process of transformation.</blockquote><p><strong>As the computer scientist Edsger W. Dijkstra famously quipped:</strong> <em>“If debugging is the process of removing software bugs, then programming must be the process of putting them in.”</em></p><p>Every red error message that appears on your screen is an invitation to learn something new and deepen your understanding of the systems you are building. It’s not wasted time; it’s an investment in your own expertise.</p><p>The next time your code breaks, will you see it as a roadblock, or as an opportunity to become a better developer?</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=7c8a06d18f16" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[React Native Reanimated 4 Stable Out — Animations by CSS! ]]></title>
            <link>https://medium.com/@anisurrahmanbup/react-native-reanimated-4-stable-out-animations-by-css-0dbe8dbf24e3?source=rss-d463021d2ee9------2</link>
            <guid isPermaLink="false">https://medium.com/p/0dbe8dbf24e3</guid>
            <category><![CDATA[react-native-reanimated]]></category>
            <category><![CDATA[react-native]]></category>
            <category><![CDATA[react20bulletin]]></category>
            <dc:creator><![CDATA[Anis  React20Bulletin]]></dc:creator>
            <pubDate>Sun, 03 Aug 2025 17:22:15 GMT</pubDate>
            <atom:updated>2025-08-03T17:24:04.535Z</atom:updated>
            <content:encoded><![CDATA[<h3>React Native Reanimated 4 Stable Out — Animations by CSS! 🙀</h3><h4>The CSS-based animations and transitions API simplifies code writing.</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*tPt1hlbosPJP4jyS.png" /><figcaption>SUBSCRIBE ➜ <a href="https://anisrncore.substack.com/"><strong>anisrncore.substack.com</strong></a></figcaption></figure><p>Six months ago, the <a href="https://github.com/software-mansion/react-native-reanimated/releases/tag/4.0.0-beta.1">Software Mansion team released the beta version of React Native Reanimated 4</a>, and last week, they <a href="https://github.com/software-mansion/react-native-reanimated/releases/tag/4.0.0"><strong>finally released its stable version</strong></a>. The team described this release as another significant milestone in the development history of this SDK. Featuring</p><ul><li><strong>Animations and Transitions</strong> now by CSS! 🔥</li><li>Introduced new <strong>React Native Worklets</strong> SDK 🚀</li><li><strong>Easy migration</strong> — From 3.x to 4.x 💯</li></ul><h3>🔥️ Article written by ➜ <a href="https://anisrncore.substack.com/">𝑹𝒆𝒂𝒄𝒕20𝑩𝒖𝒍𝒍𝒆𝒕𝒊𝒏</a> Team</h3><p>Get top <strong>20 React</strong> &amp; <strong>React Native</strong> news like this <strong>every Tuesday</strong> <strong>— right in your inbox (1 MAIL) via</strong> <strong>𝑹𝒆𝒂𝒄𝒕20𝑩𝒖𝒍𝒍𝒆𝒕𝒊𝒏<em> </em></strong>newsletter <strong>— </strong><a href="https://anisrncore.substack.com/"><strong>SUBSCRIBE</strong></a><strong>.</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*LRHfymXaUAuy-qcY.png" /><figcaption>SUBSCRIBE ➜ <a href="https://anisrncore.substack.com/"><strong>anisrncore.substack.com</strong></a></figcaption></figure><blockquote><em>💌 </em><a href="https://anisrncore.substack.com/"><em>SUBSCRIBE our Newsletter (on Substack)</em></a><em> 🚀</em></blockquote><h3>What is React Native Reanimated?</h3><p><a href="https://docs.swmansion.com/react-native-reanimated/">React Native Reanimated is a powerful animation library</a> for React Native apps, created and actively maintained by the Software Mansion team. It was first launched around 2019. The true benefits of this SDK include</p><ul><li><strong>Runs at 60–120 FPS</strong> for ultra-smooth visuals</li><li><strong>Works with gestures</strong> like drag, swipe, and pinch</li><li><strong>Supports physics-based animations</strong> like spring and decay</li><li><strong>Integrates with various sensors</strong> (e.g., gyroscope, keyboard)</li><li><strong>Cross-platform</strong>: works on iOS, Android, and even Web</li></ul><p><em>Now let’s check out what’s new in the v4 release 🚀</em></p><h3>CSS Animations and Transitions!</h3><p>In this new release of <strong>Reanimated version 4</strong>, <a href="https://blog.swmansion.com/reanimated-4-stable-release-the-future-of-react-native-animations-ba68210c3713">the team introduced a CSS-based animations and transitions API</a>. The team hopes that these CSS-based animations and transitions will make Reanimated more accessible for developers coming from the web, and also that React Native developers will be able to stay familiar with the same <a href="https://docs.swmansion.com/react-native-reanimated/docs/category/css-animations"><strong>CSS APIs across all platforms</strong></a>.</p><p>Another benefit is that <a href="https://blog.swmansion.com/reanimated-4-stable-release-the-future-of-react-native-animations-ba68210c3713">CSS animations are much easier to optimize</a>, because with CSS-style animations, Reanimated knows exactly:</p><ul><li>Which components are being animated</li><li>Which properties (like opacity, scale, etc.) are changing. This makes it easier for Reanimated to improve performance behind the scenes.</li></ul><p>But in older Reanimated setups, figuring out what’s being animated required extra calculations. <strong>But from Reanimated 4 onward, these extra calculations are no longer needed.</strong> As a result, Reanimated 4 now offers:</p><ul><li>Less code (no need for hooks like <strong><em>useSharedValue</em></strong>)</li><li>Runs faster</li><li>More performance boosts in future updates</li></ul><h3>New React Native Worklets SDK</h3><p>The <a href="https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/glossary/#worklet"><strong>Worklets</strong></a> concept was first introduced with Reanimated 2 in 2021. Worklets are short-running JavaScript functions that can run on the <a href="https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/glossary/#ui-thread"><strong>UI thread</strong></a> (the native thread that can run your code natively under the hood with high performance and without disturbing any FPS during UI rendering). Reanimated uses worklets to <strong>calculate view styles</strong> and <strong>react to events on the UI thread</strong>.</p><p>Now in Reanimated 4, the team has separated all the worklets code into a new SDK, <a href="https://www.npmjs.com/package/react-native-worklets"><strong><em>react-native-worklets</em></strong></a>, and Reanimated now uses this SDK as an internal dependency. The team did this to better support independent progress and to open it up for other non-animation packages to utilize.</p><h3>Easy migration — From 3.x to 4.x 💯</h3><p><a href="https://blog.swmansion.com/reanimated-4-stable-release-the-future-of-react-native-animations-ba68210c3713">Reanimated 4.x introduces only minor renames in styling APIs</a>, and all the animation logic you’ve written using Reanimated v2 or v3 APIs works seamlessly in 4.x. You can adopt CSS animations and transitions in your codebase incrementally, at your own pace.</p><p>The important point is that <strong>Reanimated 4.x supports only the New Architecture</strong> and no longer supports the Legacy Architecture.</p><p>Additionally, when shifting to Reanimated 4.x, you need to install the <a href="https://www.npmjs.com/package/react-native-worklets"><strong><em>react-native-worklets</em></strong></a> package using your package manager, then change <strong><em>‘react-native-reanimated/plugin’</em></strong> to <strong><em>‘react-native-worklets/plugin’</em></strong> in your <strong><em>babel.config.js</em></strong> file, and finally rebuild your Apps.</p><p>Check out more details about <a href="https://docs.swmansion.com/react-native-reanimated/docs/guides/migration-from-3.x">migrating from Reanimated 3.x to 4.x</a>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*sd2CZl-7TWRUCLoh.png" /></figure><h3>🩵 <strong>Enjoyed the read?</strong></h3><p>Get top <strong>20 React</strong> &amp; <strong>React Native</strong> news like this <strong>every Tuesday</strong> <strong>— right in your inbox (1 MAIL) via</strong> <strong>𝑹𝒆𝒂𝒄𝒕20𝑩𝒖𝒍𝒍𝒆𝒕𝒊𝒏<em> </em></strong>newsletter <strong>— </strong><a href="https://anisrncore.substack.com/"><strong>SUBSCRIBE</strong></a><strong>.</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*Q19EyGFXyNHgB0gU.png" /><figcaption>SUBSCRIBE ➜ <a href="https://anisrncore.substack.com/"><strong>anisrncore.substack.com</strong></a></figcaption></figure><blockquote><em>💌 </em><a href="https://anisrncore.substack.com/"><em>SUBSCRIBE our Newsletter (on Substack)</em></a><em> 🚀</em></blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*DmJVXByFyClxqDkL.png" /><figcaption>SUBSCRIBE ➜ <a href="https://anisrncore.substack.com/"><strong>anisrncore.substack.com</strong></a></figcaption></figure><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=0dbe8dbf24e3" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Sentry’s Godot SDK 1.0 (Alpha) released — Debugging is now easier ]]></title>
            <link>https://medium.com/@anisurrahmanbup/sentrys-godot-sdk-1-0-alpha-released-debugging-is-now-easier-736eec504ba9?source=rss-d463021d2ee9------2</link>
            <guid isPermaLink="false">https://medium.com/p/736eec504ba9</guid>
            <category><![CDATA[godot-engine]]></category>
            <category><![CDATA[react20bulletin]]></category>
            <category><![CDATA[react]]></category>
            <dc:creator><![CDATA[Anis  React20Bulletin]]></dc:creator>
            <pubDate>Thu, 31 Jul 2025 16:19:53 GMT</pubDate>
            <atom:updated>2025-07-31T16:19:53.210Z</atom:updated>
            <content:encoded><![CDATA[<h3>Sentry’s Godot SDK 1.0 (Alpha) released — Debugging is now easier 🚀</h3><h4>Sentry’s Godot SDK version 1.0 Alpha now supports Godot 4.5 Beta</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*LAeDNQUrR0XAWsmC-BRHVQ.png" /></figure><p>Last week Sentry team released <a href="https://blog.sentry.io/introducing-sentrys-godot-sdk-1-0-alpha-with-support-for-godot-4-5-beta/"><strong>Sentry’s Godot SDK 1.0</strong></a>, which is currently in <strong>Alpha</strong> release — supports <a href="https://godotengine.org/article/dev-snapshot-godot-4-5-beta-3/"><strong>Godot 4.5 Beta</strong></a>.</p><blockquote>Let’s first understand the basics of what Godot SDK, Sentry, etc.</blockquote><h3>🔥️ Article written by ➜ <a href="https://anisrncore.substack.com/">𝑹𝒆𝒂𝒄𝒕20𝑩𝒖𝒍𝒍𝒆𝒕𝒊𝒏</a> Team</h3><p>Get <strong>20 React</strong> &amp; <strong>React Native</strong> updates <strong>every Tuesday</strong> <strong>— right in your inbox (MAIL) via</strong> 𝑹𝒆𝒂𝒄𝒕20𝑩𝒖𝒍𝒍𝒆𝒕𝒊𝒏<strong><em> </em></strong>newsletter <strong>— </strong><a href="https://anisrncore.substack.com/"><strong>SUBSCRIBE Now</strong></a><strong>.</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*Fgm2Bxnk3PlaQVzL.png" /><figcaption><a href="https://anisrncore.substack.com/">https://anisrncore.substack.com/</a></figcaption></figure><blockquote>💌 <a href="https://anisrncore.substack.com/">SUBSCRIBE our Newsletter (on Substack)</a> 🚀</blockquote><h3>What is Godot SDK?</h3><p><a href="https://godotengine.org/"><strong>Godot SDK</strong></a> (written in C++) is a toolkit designed to help game developers <a href="https://docs.godotengine.org/en/stable/getting_started/introduction/introduction_to_godot.html#what-is-godot"><strong>create games using the Godot engine</strong></a>, which is a popular free and open-source platform for both <a href="https://docs.godotengine.org/en/stable/getting_started/first_2d_game/index.html"><strong>2D</strong></a> and <a href="https://docs.godotengine.org/en/stable/getting_started/first_3d_game/index.html"><strong>3D game</strong></a> development.</p><h3>What is Sentry?</h3><p><a href="https://sentry.io/welcome/"><strong>Sentry is a tool that acts like a smart error detective for your software and games</strong></a><strong>.</strong> It helps developers monitor, track, and fix problems like crashes, bugs, or unexpected behaviors in real-time — even after their product is live to their users.</p><h3>What is Sentry’s Godot SDK?</h3><p>Okay, now the <a href="https://sentry.io/for/godot/"><strong>Sentry’s Godot SDK</strong></a> is a custom plugin that has been made to connect <a href="https://sentry.io/welcome/"><strong>Sentry’s</strong></a><strong> </strong>powerful error-tracking features directly with <a href="https://docs.godotengine.org/en/stable/getting_started/introduction/introduction_to_godot.html#what-is-godot"><strong>Godot SDK</strong></a> for <strong>Godot-based games</strong>. It’s like giving your game the ability to talk back when something goes wrong.</p><h3>Introducing Sentry’s Godot SDK — v1.0 (Alpha)</h3><p>Historically, <a href="https://docs.godotengine.org/en/stable/getting_started/step_by_step/index.html"><strong>Godot</strong></a> has lacked some of the debugging functionality available in other game engines, but with <a href="https://godotengine.org/article/dev-snapshot-godot-4-5-beta-3/"><strong>Godot 4.5 (currently in beta)</strong></a>, you now get built-in support for <strong>script stack traces</strong> (a step-by-step record of function calls), so when something breaks at runtime, you can see what led up to it, even outside the editor.</p><p>Building on that progress, <a href="https://blog.sentry.io/introducing-sentrys-godot-sdk-1-0-alpha-with-support-for-godot-4-5-beta/#introducing-sentrys-godot-sdk-10"><strong>Sentry’s new Godot SDK 1.0 (currently in alpha)</strong></a> has onboarded <a href="https://godotengine.org/article/dev-snapshot-godot-4-5-beta-3/"><strong>Godot 4.5 beta</strong></a>,<strong> </strong>which expands visibility into live crashes and runtime errors for <a href="https://github.com/godotengine/godot"><strong>Godot developers</strong></a>. With full GDScript stack traces, native crash reporting, and contextual breadcrumbs, so you can fix production issues fast, without waiting on player reports or parsing logs looking for answers.</p><p><strong><em>NOTE:</em></strong> <a href="https://gdscript.com/"><strong>GDScript</strong></a><strong> is a scripting language made for Godot</strong>. Godot developers use this language to write their game&#39;s logic files.</p><h3>What’s new in Sentry’s Godot SDK 1.0 (Alpha)?</h3><p>With the release of <strong>Godot 4.5 beta</strong>, the <strong>Sentry Godot SDK 1.0</strong> now supports:</p><ul><li><strong>Full GDScript stack traces</strong> — step-by-step record of function calls made in your GDScript code.</li><li><strong>The new Godot logger interface </strong>— Logs now include exact line numbers, making it easier to trace issues &amp; many more features with the new interface.</li><li><strong>Better debugging — </strong>you can now attach custom logs and config files to your error reports, giving you (or your team) a clear view of <strong><em>what the player was doing</em></strong>, <strong><em>what settings were active</em></strong>, and <strong><em>what the game engine was processing</em></strong> before the crash.</li></ul><p>No more chasing vague bug reports — Sentry delivers clear, structured insights with full error context, so you can trace the issue, test your fix, and confidently ship a patch that keeps players moving forward.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*KMUxbczqCZvFSq7a.png" /></figure><p>🩵 <strong>Enjoyed the read? </strong>Get <strong>20 React</strong> &amp; <strong>React Native</strong> updates <strong>every Tuesday</strong> <strong>— right in your inbox (MAIL) via</strong> <strong>𝑹𝒆𝒂𝒄𝒕20𝑩𝒖𝒍𝒍𝒆𝒕𝒊𝒏<em> </em></strong>newsletter <strong>— </strong><a href="https://anisrncore.substack.com/"><strong>SUBSCRIBE</strong></a><strong>.</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*Fgm2Bxnk3PlaQVzL.png" /><figcaption><a href="https://anisrncore.substack.com/">https://anisrncore.substack.com/</a></figcaption></figure><blockquote>💌 <a href="https://anisrncore.substack.com/">SUBSCRIBE our Newsletter (on Substack)</a> 🚀</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*-cWkZn5UfvmJ75Uw.png" /><figcaption><a href="https://anisrncore.substack.com/">https://anisrncore.substack.com/</a></figcaption></figure><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=736eec504ba9" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[ 20 ⁂ 002  ⚛️]]></title>
            <link>https://medium.com/@anisurrahmanbup/20-002-%EF%B8%8F-89a8ae3a831c?source=rss-d463021d2ee9------2</link>
            <guid isPermaLink="false">https://medium.com/p/89a8ae3a831c</guid>
            <category><![CDATA[react-native]]></category>
            <category><![CDATA[react]]></category>
            <category><![CDATA[react-new-feature]]></category>
            <category><![CDATA[react-native-news]]></category>
            <category><![CDATA[react20bulletin]]></category>
            <dc:creator><![CDATA[Anis  React20Bulletin]]></dc:creator>
            <pubDate>Thu, 31 Jul 2025 01:19:53 GMT</pubDate>
            <atom:updated>2025-07-31T01:20:58.848Z</atom:updated>
            <content:encoded><![CDATA[<h4>Sentry’s Godot SDK 1.0, Shadcn/v0 registry, React Router v7, React Native Reanimated 4, RN 0.81 &amp; Expo SDK 54, Nitrogen, RN-fast-shimmer</h4><p>Hello <strong>React</strong> &amp; <strong>ReactNative</strong> devs,</p><p>Last week was a real shipping week — lots of exciting stuff landed. The major highlights</p><ul><li><strong>Sentry’s Godot SDK</strong> hit 1.0,</li><li><strong>Shadcn/v0</strong> launched its registry,</li><li>React Native <strong>Reanimated 4</strong> went stable, and</li><li>Expo SDK 54 (coming with 0.81) <strong>announced 10x faster iOS builds</strong>.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*J0cLHvgwp-oVAHE8.png" /></figure><p><em>☕️ Coffee in hand? Let’s scroll through today’s gems 😇</em></p><p><strong><em>NOTE:</em></strong> 🔥 <a href="https://anisrncore.substack.com/p/20-002"><strong><em>It was originally published on Substack (React20Bulletin Newsletter) </em></strong></a><em>— </em><strong><em>Subscribe</em></strong><em> now to get the newsletters delivered straight to your inbox every </em><strong><em>Tuesday</em></strong><em>! ➜ </em><a href="https://anisrncore.substack.com/"><strong><em>SUBSCRIBE (on Substack)</em></strong></a></p><blockquote>💌 <a href="https://anisrncore.substack.com/">SUBSCRIBE on Substack</a> — 1 mail every TUESDAY</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*C5YgA7uYGVC_RIIR.png" /></figure><h3>🔮 Sponsor</h3><p><strong>Hire a World-Class Dev Team for Your Next Big Idea 🚀</strong> — Trusted by startups and enterprises across the USA, Europe, Dubai, and beyond, our senior full-stack team brings 9+ years of experience in 🔹 <strong><em>Mobile (React Native)</em></strong>, 🔹 <strong><em>Web (React)</em></strong>, and 🔹 <strong><em>Blockchain (Ethereum, Solana)</em></strong>, we deliver high-performance solutions — from MVP to full-scale launch 🚀.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*wUWm89zkJP3tAGZn.png" /></figure><p>Feel free to reach out directly via: <strong>Email:</strong> <a href="mailto:anisurrahmanbup@gmail.com"><strong>anisurrahmanbup@gmail.com</strong></a> or <strong>X (Twitter):</strong> <a href="https://x.com/anis_RNCore"><strong>@anis_RNCore</strong></a></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*6R0m0xCIlO_qwLI-.png" /></figure><h3>⚛️ All the Hot React Updates 🚀</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*PuSH0nJDyald2nwT.png" /></figure><h3>🔸 Introducing Sentry’s Godot SDK 1.0 🚀</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*BxOy_yliUjFDFyOK.png" /></figure><p><a href="https://sentry.io/for/godot/"><strong>Sentry’s Godot SDK</strong></a> helps Godot developers <a href="https://sentry.io/solutions/sentry-for-game-developers/">fix game issues</a> faster by catching errors, <a href="https://docs.sentry.io/platforms/godot/enriching-events/screenshots/">Screenshots</a>, <a href="https://docs.sentry.io/platforms/godot/enriching-events/tags/">Tags</a>, <a href="https://docs.sentry.io/platforms/godot/enriching-events/breadcrumbs/">Breadcrumbs</a>, and helpful <a href="https://docs.sentry.io/platforms/godot/enriching-events/context/">contexts</a>. With <a href="https://x.com/getsentry/status/1948091249530913192">version 1.0 Alpha, it now supports Godot 4.5 Beta</a>, adding full <a href="https://blog.sentry.io/introducing-sentrys-godot-sdk-1-0-alpha-with-support-for-godot-4-5-beta/"><strong>GDScript stack traces</strong></a> (step-by-step record of function calls), a new Godot logger interface, and better error tracking features.</p><h3>🔸 Introducing shadcn/v0 Registry 🔥</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*9fFsUKMugyXKJjee.png" /></figure><p>Vercel introduced <a href="https://v0.dev/"><strong>v0.dev</strong></a> back in October 2024 as an <strong>AI-powered UI builder</strong> that lets you generate customized UI components simply by saying things like <em>“Modify Navbar to Red!”</em><strong> However, they’ve now taken it a step further </strong>— <a href="https://x.com/jacobmparis/status/1948902443452154194"><strong>last week, they launched the shadcn/v0 registry</strong></a>, which <a href="https://vercel.com/templates/next.js/shadcn-ui-registry-starter">lets you publish those customized components in JSON files with a public URL</a>, install them easily using the Shadcn CLI in your project (<a href="https://ui.shadcn.com/docs/registry">React, Vite &amp; many more</a>), and edit them anytime via <a href="https://v0.dev/community/shadcn-v0-registry-tSXOjooGIga"><strong>v0.dev</strong></a>.</p><h3>🔸 More React News Inside 👇</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*ALxw1KvEwcjoMVJP.png" /></figure><ul><li><a href="https://x.com/AlemTuzlak/status/1946520402009739577"><strong>Alem Tuzlak</strong> made an up-to-date implementation of auth</a> in his <a href="https://github.com/forge-42/base-stack"><strong>Forge 42 base-stack</strong></a> (a basic setup for projects to start with <strong>React Router v7</strong>).</li><li>New docs on <a href="https://x.com/schanuelmiller/status/1948094441341813235"><strong>Automatic Code Splitting in TanStack Router</strong> are live</a>!</li><li><strong>Next.js Conf</strong> returns to San Francisco this October — <a href="https://x.com/nextjs/status/1949935608735866957">Submit your talk ideas if you’d like to speak</a>.</li><li>Exciting new <a href="https://x.com/thesegunadebayo/status/1948065676838748665"><strong>JSON viewer</strong> (a component that can log JSON data in a tree structure) shipped in <strong>Ark UI</strong></a> (component library for React &amp; others)</li><li><a href="https://anisrncore.substack.com/i/169553968/all-the-hot-react-updates">More <strong>React</strong> news in <strong>today’s draft</strong></a> — check out our <a href="https://anisrncore.substack.com/i/169553968/all-the-hot-react-updates">Quick Links</a>.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*MVgLVVcpj1uoFO3G.png" /></figure><blockquote><a href="https://anisrncore.substack.com/"><strong><em>SUBSCRIBE to the Newsletter on Substack to get the issues directly to your MAIL — Every Tuesday.</em></strong></a></blockquote><blockquote>💌 <a href="https://anisrncore.substack.com/">SUBSCRIBE on Substack</a> — 1 mail every TUESDAY</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*d5IZwFBjQcyAKqhA.png" /></figure><h3>🩵 Today’s — Dev of the Week 🎖️</h3><p>Meet <a href="https://www.linkedin.com/in/favaz-p-a-a434441b8/"><strong>Favaz</strong></a> — <strong>Senior React Native Dev</strong> &amp; Team Lead with 5+ years of experience building scalable, user-friendly apps for fintech, logistics, and real-time comms. Expert in Socket.IO, Stripe, modular code, and cross-platform architecture.</p><p>💬 <em>Need help with Mobile Solutions? </em><a href="https://www.linkedin.com/in/favaz-p-a-a434441b8/"><em>Reach out to Favaz (or Hire) for expert guidance</em></a><em>.</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*4_PNEVI2cRsrSech.png" /></figure><blockquote><em>Thanks to Favaz </em><a href="https://www.linkedin.com/posts/favaz-p-a-a434441b8_react20bulletin-why-subscribe-activity-7355871216974381056-lp_h?utm_source=share&amp;utm_medium=member_desktop&amp;rcm=ACoAACTSeaQBhT5gKLvTCnzx-bF4Gx1od8jqgSM"><em>for his shoutout on LinkedIn about </em><strong><em>React20Bulletin</em></strong></a><em> 💞</em></blockquote><blockquote>💌 <a href="https://anisrncore.substack.com/">SUBSCRIBE on Substack</a> — 1 mail every TUESDAY</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*RDOz1nUdR0f5Ie2G.png" /></figure><h3>⚛️ All the Hot React Native Updates</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*HpMA9Q48pgQxivD_.png" /></figure><h3>🔹 React Native Reanimated 4 — Stable 🔥</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*JuOV_ebD-7ZyjMX8.png" /></figure><p>After six months of development, the <a href="https://blog.swmansion.com/reanimated-4-stable-release-the-future-of-react-native-animations-ba68210c3713">Software Mansion team has finally released <strong>Reanimated 4 (Stable)</strong></a>. Key updates include:</p><ul><li>The <a href="https://docs.swmansion.com/react-native-reanimated/docs/category/css-animations/"><strong>CSS-based animations</strong></a><strong> </strong>and<strong> </strong><a href="https://docs.swmansion.com/react-native-reanimated/docs/category/css-transitions/"><strong>transitions API</strong></a> simplifies code writing.</li><li><a href="https://docs.swmansion.com/react-native-reanimated/docs/guides/worklets">React Native worklets</a> (small functions that can run on Native/UI thread) <strong>now handle multithreading with more care</strong>, letting you offload heavy logic — even when your app is busy.</li></ul><p><strong><em>Additional Updates:</em></strong> <a href="https://www.youtube.com/watch?v=Wr2fOM_xD2I&amp;t=149s">Worklets code is now in a separate package</a> — reducing bundle size and fully supporting the New Architecture, with no migration changes required.</p><h3>🔹 10x Faster iOS Builds — RN 0.81 🚀</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*nbW37OVE6JqaQbxH.png" /></figure><p>In <strong>React Native 0.81</strong> and <strong>Expo SDK 54</strong>, <a href="https://x.com/expo/status/1948469516654313625"><strong>Expo</strong> — together with <strong>Meta</strong> — is introducing <strong>Precompiled React Native builds for iOS</strong></a> — <a href="https://expo.dev/blog/precompiled-react-native-for-ios#before-and-after-examples-">reducing compile times in apps by up to 10x.</a> That means no more building the same code day in and day out. However, <a href="https://github.com/facebook/hermes/issues/17">precompilation was already introduced on Android by the Hermes team</a> a couple of years ago.</p><h3>🔹 More React Native News Inside 👇</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*4PMwoUITG71saH9O.png" /></figure><ul><li><a href="https://x.com/thymikee/status/1947601496176267777"><em>Incremental React Native Adoption in Native Apps</em></a> — a book by Callstack.</li><li><a href="https://x.com/mrousavy/status/1947381904237289877">Marc Rousavy made Nitrogen</a> (TypeScript-to-native code generator) <a href="https://github.com/mrousavy/nitro/pull/767"><strong>4x faster</strong></a> 🚀</li><li><a href="https://www.callstack.com/blog/expanding-on-device-apple-llm-capabilities-introducing-tool-calling"><strong>Introducing Tool Calling in react-native-ai/apple</strong></a>: LLMs can now access apps like Calendar or Weather for fast &amp; accurate answers.</li><li><a href="https://x.com/grabbou/status/1948385538802675929">Callstack drops <strong>react-native-fast-shimmer</strong></a> for quick loading visuals. (<a href="https://github.com/callstack/react-native-fast-shimmer">GitHub</a>)</li><li>Three blogs published on <a href="https://x.com/grabbou/status/1948384325608591701"><strong>speeding up cross-platform apps</strong> &amp; their native components</a>.</li><li><a href="https://anisrncore.substack.com/i/169553968/all-the-hot-react-native-updates">More <strong>React Native news</strong> in <strong>today’s draft</strong></a> — check out our <a href="https://anisrncore.substack.com/p/20-002-quick-links"><strong>Quick Links</strong></a>.</li></ul><blockquote><a href="https://anisrncore.substack.com/"><strong><em>SUBSCRIBE to the Newsletter on Substack to get the issues directly to your MAIL — Every Tuesday.</em></strong></a></blockquote><blockquote>💌 <a href="https://anisrncore.substack.com/">SUBSCRIBE on Substack</a> — 1 mail every TUESDAY</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*2itD__R9jtjk2RrI.png" /></figure><h3>🎬 New Dev Content — Live?</h3><ul><li><a href="https://youtu.be/HDDmaVEMv1w"><strong>React Native Authentication with Expo Router v5</strong></a> — by Simon Grimm.</li><li><a href="https://youtu.be/nlMyplRL8V8"><strong>How to Use Claude Code with React Native (Step-by-Step)</strong></a> — by Beto.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*hE0l7PFARrQg_6gS.png" /></figure><h3>💼 React Jobs — Now Hiring 🔥</h3><ul><li>Passionate about AI tooling — in Getsentry <strong>— </strong><a href="https://x.com/jshchnz/status/1949988929740157100"><strong>Apply Here</strong></a>.</li><li>React — Remote-first — Berlin-based <strong>— </strong><a href="https://x.com/adnansahinovich/status/1949425867827843582"><strong>Apply Here</strong></a>.</li><li>Design engineer for Shopify — <a href="https://x.com/mxstbr/status/1948478054684393481"><strong>Apply Here</strong></a>.</li><li>React Native, React, full-stack, Swift — <a href="https://x.com/danscan/status/1948823939674734846"><strong>Apply Here</strong></a>.</li></ul><blockquote><strong><em>Got a React or React Native job opening?</em></strong><em> </em><a href="https://x.com/anis_RNCore"><em>Send it to me</em></a><em> only if it’s legit — I share authentic roles from trusted companies. No scams.</em></blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*AxInaKhWQPPfAh46.png" /></figure><h3>🤖 AI Updates — You’ll Love</h3><ul><li><a href="https://x.com/OpenAI/status/1947628731142648113"><strong>OpenAI is developing 4.5 gigawatts of additional Stargate</strong></a> data center capacity with Oracle in the U.S.</li><li><a href="https://vercel.com/blog/model-context-protocol-mcp-explained">What is MCP? <strong>explained by Vercel</strong>.</a> (MCP gives AI models control to other apps to place an order, write a file &amp; many more)</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*MUESrrI1F5lDoTjq.png" /></figure><h3>🤔 Pro Programming Tips</h3><ul><li>Don’t start with learning. <a href="https://x.com/OzolinsJanis/status/1945090355138805971"><strong>Start with doing</strong> and learn when you get stuck</a>.</li><li><strong>Become a React.js Pro</strong> in No Time — <a href="https://www.linkedin.com/posts/ali-raza-19431324b_reactjs-webdevelopment-frontend-activity-7353201403261050880-or2R?utm_source=share&amp;utm_medium=member_desktop&amp;rcm=ACoAACTSeaQBhT5gKLvTCnzx-bF4Gx1od8jqgSM">Grab This Handy Cheatsheet</a>!</li></ul><blockquote><a href="https://anisrncore.substack.com/"><strong><em>SUBSCRIBE to the Newsletter on Substack to get the issues directly to your MAIL — Every Tuesday.</em></strong></a></blockquote><blockquote>💌 <a href="https://anisrncore.substack.com/">SUBSCRIBE on Substack</a> — 1 mail every TUESDAY</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*D0pMOVWs_Uxd5pmh.png" /></figure><h3>🏕️ Extras You Shouldn’t Miss</h3><ul><li><a href="https://x.com/o_kwasniewski/status/1949809589479756108">Introducing <strong>Screeny.dev</strong></a> — add a nice background to your images &amp; share!</li><li><a href="https://x.com/crsamra/status/1948050596029952000"><strong>Introducing Waves</strong>, camera glasses for creators.</a></li></ul><blockquote>💌 <a href="https://anisrncore.substack.com/">SUBSCRIBE on Substack</a> — 1 mail every TUESDAY</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*8kvYalGdEXqwg_G-.png" /></figure><h3>💟 Partner with React20Bulletin</h3><p>💟 <strong>Sponsor With Us </strong>→<strong> </strong><a href="https://anisrncore.substack.com/p/sponsor"><strong>Click here</strong></a></p><p>💼 <strong>Hire Our Dev Team</strong> → <a href="https://anisrncore.substack.com/i/167807220/hire-our-dev-team-idea-to-app"><strong>Click here</strong></a></p><p>💯 <strong>More about Newsletter/ Author</strong> → <a href="https://anisrncore.substack.com/about"><strong>Click here</strong></a></p><p>😍 <strong>Support us</strong> <strong>on</strong> → <a href="https://medium.com/@anisurrahmanbup"><strong>Medium</strong></a>, <a href="https://x.com/React20Bulletin"><strong>X (Twitter)</strong></a>, <a href="https://www.linkedin.com/in/anis-react20bulletin/"><strong>LinkedIn</strong></a><strong>,</strong> and <a href="https://bsky.app/profile/react20bulletin.bsky.social"><strong>🦋 Bluesky</strong></a>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*WpZva6qC-xeZ20jp.png" /></figure><blockquote><a href="https://anisrncore.substack.com/"><strong><em>SUBSCRIBE to the Newsletter on Substack to get the issues directly to your MAIL — Every Tuesday.</em></strong></a></blockquote><blockquote>💌 <a href="https://anisrncore.substack.com/">SUBSCRIBE on Substack</a> — 1 mail every TUESDAY</blockquote><p><strong><em>🔹</em></strong><em> Thanks for subscribing to </em><a href="https://anisrncore.substack.com/"><strong>React20Bulletin</strong></a><em>. This post is public, so feel free to share it. ➜ </em><a href="https://anisrncore.substack.com/p/birth-of-react20bulletin-001?utm_source=substack&amp;utm_medium=email&amp;utm_content=share&amp;action=share&amp;token=eyJ1c2VyX2lkIjo5NDQwNDAwMCwicG9zdF9pZCI6MTUwOTI3OTc4LCJpYXQiOjE3NTM1MzAzODYsImV4cCI6MTc1NjEyMjM4NiwiaXNzIjoicHViLTMyNTMxNTAiLCJzdWIiOiJwb3N0LXJlYWN0aW9uIn0.v6rR2mny3FhtGyn7oHDagAIvRv0ismi-84QOfxG-u3s">Share</a></p><p><strong><em>🔹 Help shape the next issue — we’d love your thoughts! ➜ </em></strong><a href="https://anisrncore.substack.com/survey/3912689?token=">Give your Feedback!</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=89a8ae3a831c" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[ React20Bulletin — NextJS 15.4 released ]]></title>
            <link>https://medium.com/@anisurrahmanbup/react20bulletin-nextjs-15-4-released-b72a5fb36371?source=rss-d463021d2ee9------2</link>
            <guid isPermaLink="false">https://medium.com/p/b72a5fb36371</guid>
            <category><![CDATA[nextjs]]></category>
            <category><![CDATA[react20bulletin]]></category>
            <dc:creator><![CDATA[Anis  React20Bulletin]]></dc:creator>
            <pubDate>Sat, 26 Jul 2025 20:01:44 GMT</pubDate>
            <atom:updated>2025-07-26T20:01:44.938Z</atom:updated>
            <content:encoded><![CDATA[<h3>💌 React20Bulletin — NextJS 15.4 released 🚀</h3><h4><strong>Turbopack builds enhancements &amp; Performance Improvements</strong></h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Z5oFL6-yfrBwrD1_W1OPGw.png" /></figure><p>Last week, <a href="https://vercel.com/home?utm_source=next-site&amp;utm_medium=banner&amp;utm_campaign=blog_next-15-4">Vercel</a> dropped <a href="https://x.com/nextjs/status/1944881550270849424"><strong>Next.js 15.4</strong></a> — packed with over <a href="https://github.com/vercel/next.js/releases/tag/v15.4.1">140 commits from 40 contributors</a>. This release improves <a href="https://nextjs.org/blog/next-15-4">Turbopack Builds, performance, and stability</a>. Highlights include:</p><ul><li><strong>Turbopack Builds:</strong> Starting from <strong>15.4</strong>, when you run the <strong><em>next build</em></strong> command with <strong><em>— turbopack</em></strong>, all <a href="https://areweturboyet.com/">8,298 production tests</a> now pass successfully. <a href="https://nextjs.org/docs/app/api-reference/turbopack"><strong>Turbopack</strong></a> is a super-fast bundler for Next.js, written in <strong>Rust</strong>, that combines your code, images, and assets to make builds faster and smarter — and <a href="https://nextjs.org/docs/app/api-reference/turbopack#unsupported-and-unplanned-features">it replaces Webpack</a> (written in JS). With this, 15.4 is now more stable, and the team is already working on a <strong>beta for Next.js 16</strong>!</li><li><strong>Performance Improvements:</strong> <a href="https://github.com/vercel/next.js/releases/tag/v15.4.1">Next.js 15.4</a> now handles faster page loads by prefetching data more efficiently and using better caching, along with smarter error handling.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*C2z51MsmQdfydI-T.png" /></figure><p>🎉 <strong>Enjoyed the read? Don’t miss out — </strong><a href="https://anisrncore.substack.com/"><strong>Subscribe to React20Bulletin (Newsletter)</strong></a><strong> </strong>and get the latest dev buzz, tips, and tech updates right in your inbox (Mail) on <strong>every Tuesday</strong>.</p><blockquote>💌 <a href="https://anisrncore.substack.com/">SUBSCRIBE our Newsletter (on Substack)</a> 🚀</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*IbM1PYHYAIvbaZhj.png" /><figcaption><a href="https://anisrncore.substack.com/">https://anisrncore.substack.com/</a></figcaption></figure><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=b72a5fb36371" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[ Birth of React20Bulletin  001]]></title>
            <link>https://medium.com/@anisurrahmanbup/birth-of-react20bulletin-001-bf4428cded73?source=rss-d463021d2ee9------2</link>
            <guid isPermaLink="false">https://medium.com/p/bf4428cded73</guid>
            <category><![CDATA[react20bulletin]]></category>
            <category><![CDATA[react]]></category>
            <category><![CDATA[react-new-feature]]></category>
            <category><![CDATA[reactnativeappdevelopment]]></category>
            <dc:creator><![CDATA[Anis  React20Bulletin]]></dc:creator>
            <pubDate>Sat, 26 Jul 2025 12:52:35 GMT</pubDate>
            <atom:updated>2025-07-26T14:33:43.616Z</atom:updated>
            <content:encoded><![CDATA[<h4>Next.js 15.4, NuxtLabs joining Vercel, React Router supports RSC, TanStack Start supports Selective SSR, RN SCreens Overhaul, Unistyles 3.0, Ignite 11</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*qjlLLqT3oWAQDoN8idVYnQ.png" /></figure><p><strong><em>NOTE:</em></strong> 🔥 <a href="https://anisrncore.substack.com/p/birth-of-react20bulletin-001"><strong><em>It was originally published on Substack (React20Bulletin Newsletter)</em></strong></a><strong><em> </em></strong><em>— </em><strong><em>Subscribe</em></strong><em> now to get the newsletters delivered straight to your inbox every </em><strong><em>Tuesday</em></strong><em>! ➜ </em><a href="https://anisrncore.substack.com/"><strong><em>SUBSCRIBE (on Substack)</em></strong></a></p><blockquote>💌 <a href="https://anisrncore.substack.com/">SUBSCRIBE this Newsletter (on Substack)</a> 🚀</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*LMV-4ATBeVRpN_xw.png" /></figure><p>Hello <strong>React</strong> &amp; <strong>ReactNative</strong> devs,</p><p>Welcome to the newsletter, <a href="https://anisrncore.substack.com/"><strong>React20Bulletin (in Substack)</strong></a><strong> 🩵</strong>. Some of you already know me from my book, <a href="https://github.com/anisurrahman072/React-Native-Advanced-Guide">React Native Advanced Guide Book</a>, which has secured over <strong>2,300</strong> GitHub stars. However, after a year of planning, <a href="https://anisrncore.substack.com/"><strong>React20Bulletin</strong></a> has finally started today 🔮.</p><p><strong><em>NOTE:</em></strong><em> Since it’s our first issue and July is nearly over, today’s newsletter covers all the major news from the start of the month 🚀.</em></p><h3>💌 Intro To React20Bulletin 💌</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*JtZTB8dPuMzF7lFM.png" /></figure><p><a href="https://anisrncore.substack.com/"><strong>React20Bulletin</strong></a> is a top-notch, <strong>beginner-friendly</strong> newsletter — bringing you the <strong>20 best React </strong>and<strong> React Native updates</strong> every <strong>Tuesday</strong>, delivered straight to your inbox (email). It covers 🔻</p><ul><li>⚛️ <strong>Top 10 React news </strong>of the week</li><li>⚛️<strong> Top 10 React Native news </strong>of the week</li><li><strong>🤖 Top AI highlights </strong>of the week</li><li><strong>💼 Open React (Native) JOB </strong>opportunities</li><li>🔥<strong> Dev of the Week </strong>spotlight ➙ ❝<strong>You in Next News</strong>❞<strong>?</strong> 👇</li></ul><blockquote><a href="https://anisrncore.substack.com/p/dev-of-the-week"><strong>Dev of the week</strong></a><em> is a chance to make </em><strong><em>your Profile, SDK, Product, or Work go viral</em></strong><em> in front of thousands of developers through the </em><a href="https://anisrncore.substack.com/"><strong><em>React20Bulletin</em></strong></a><em> newsletter at </em><strong><em>100% free </em></strong><em>of cost 💟.</em></blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*Lv7pFW8gPgiziDw9.png" /></figure><blockquote><strong>Do you want to be featured as ❝Dev of the Week❞ in next News? ➙</strong> <a href="https://anisrncore.substack.com/p/dev-of-the-week"><strong>Click here to get started</strong></a></blockquote><blockquote>💌 <a href="https://anisrncore.substack.com/">SUBSCRIBE this Newsletter (on Substack)</a> 🚀</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*cJev3CPGhT8a_TNx.png" /></figure><h3>🔮 Sponsor</h3><p><strong>Hire a World-Class Dev Team for Your Next Big Idea 🚀</strong> We’re a seasoned team of full-stack developers with over <strong>9 years of experience</strong> delivering scalable solutions across mobile, web, and blockchain.</p><p>🔹 <strong>Mobile Development</strong> — iOS &amp; Android apps powered by <strong>React Native</strong> 🔹 <strong>Web Development</strong> — Fast, responsive interfaces with <strong>React</strong> 🔹 <strong>Blockchain Expertise</strong> — Smart contracts &amp; dApps on <strong>Ethereum</strong>, <strong>Solana</strong>, and beyond.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*qa-odDIAxLvrsx1j.png" /></figure><p>We’ve successfully partnered with clients across the <strong>USA, Dubai, Europe, North America</strong>, and more — delivering tailored, high-performance products with global impact.</p><p>Whether you need a prototype, MVP, or full-scale launch, we’re ready to bring your vision to life.</p><p>Feel free to reach out directly via: <strong>Email:</strong> <a href="mailto:anisurrahmanbup@gmail.com"><strong>anisurrahmanbup@gmail.com</strong></a> or <strong>X (Twitter):</strong> <a href="https://x.com/anis_RNCore">@anis_RNCore</a></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*YDTxek-golWe-MHx.png" /></figure><h3>⚛️ All the Hot React Updates 🚀</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*Zhkld-DZwGx7ssvD.png" /></figure><h4>🔸 Next.js 15.4 released 🚀</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*3h2g1KIbC9AgceNk.png" /></figure><p>Last week, <a href="https://vercel.com/home?utm_source=next-site&amp;utm_medium=banner&amp;utm_campaign=blog_next-15-4">Vercel</a> dropped <a href="https://x.com/nextjs/status/1944881550270849424"><strong>Next.js 15.4</strong></a> — packed with over <a href="https://github.com/vercel/next.js/releases/tag/v15.4.1">140 commits from 40 contributors</a>. This release improves <a href="https://nextjs.org/blog/next-15-4">Turbopack Builds, performance, and stability</a>. Highlights include:</p><ul><li><strong>Turbopack Builds:</strong> Starting from <strong>15.4</strong>, when you run the <strong><em>next build</em></strong> command with <strong><em>— turbopack</em></strong>, all <a href="https://areweturboyet.com/">8,298 production tests</a> now pass successfully. <a href="https://nextjs.org/docs/app/api-reference/turbopack"><strong>Turbopack</strong></a> is a super-fast bundler for Next.js, written in <strong>Rust</strong>, that combines your code, images, and assets to make builds faster and smarter — and <a href="https://nextjs.org/docs/app/api-reference/turbopack#unsupported-and-unplanned-features">it replaces Webpack</a> (written in JS). With this, 15.4 is now more stable, and the team is already working on a <strong>beta for Next.js 16</strong>!</li><li><strong>Performance Improvements:</strong> <a href="https://github.com/vercel/next.js/releases/tag/v15.4.1">Next.js 15.4</a> now handles faster page loads by prefetching data more efficiently and using better caching, along with smarter error handling.</li></ul><h4>🔸 NuxtLabs is joining Vercel 💥</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*AvBqN_DVYLYCGLF3.png" /></figure><p>Big news shaking up the frontend world: <a href="https://nuxtlabs.com/"><strong>NuxtLabs is now part of Vercel</strong></a><strong>!</strong></p><p>🔹 <a href="https://nuxt.com/"><strong>Nuxt</strong></a> is a popular framework for building fast and SEO-friendly web apps with <strong>Vue.js</strong>. 🔹 <a href="https://vercel.com/"><strong>Vercel</strong></a> is a cloud platform that helps developers deploy fast, modern websites — and it’s the team behind <a href="https://nextjs.org/"><strong>Next.js</strong></a>, <strong>Turborepo</strong>, <strong>Svelte</strong>, <strong>shadcn</strong>, and more.</p><p>The Nuxt team will continue to improve <strong>Nuxt</strong> and <a href="https://nuxt.com/docs/4.x/api/kit/nitro">Nitro (Nuxt’s backend engine)</a> with the same care, while exploring ways to integrate <strong>AI</strong> into the developer experience.</p><h4>🔸 React Router now supports RSC 🔥</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*KQF4_CfHVKD3G44Q.png" /></figure><p>Another great piece of news is that <a href="https://remix.run/blog/react-router-and-react-server-components"><strong>React Router v7.7.0 now supports React Server Component (RSC)</strong></a><strong>.</strong></p><p><strong>Before RSC</strong>, React Router (also known as <a href="https://reactrouter.com/start/modes#framework">Framework Mode</a>) required additional plugins to work with bundlers like <strong>Vite</strong> or <strong>Webpack</strong>. For example, the plugin <strong><em>@react-router/fs-routes</em></strong> was needed to automatically split code for each route, and <strong><em>@react-router/dev/routes</em></strong> was used to read the <strong><em>routes.ts</em></strong> file.</p><p>But now <strong>with RSC</strong> (also known as <a href="https://reactrouter.com/start/modes#data">Data Mode</a>), <a href="https://remix.run/blog/react-router-and-react-server-components#the-rsc-way">you don’t need these plugins anymore</a> for <em>basic routing</em>, <em>UI streaming from server to client</em>, or <em>splitting code for each route</em>. All of these handle most of it natively. This reduces a lot of complexity.</p><p>Another cool thing is that, <strong>without RSC</strong>, every component needs to be bundled and sent to the browser, making users wait until all the data arrives. Now <a href="https://remix.run/blog/rsc-preview#rsc-from-loaders"><strong>with RSC</strong>, only the rendered client components are loaded on the server</a> and sent immediately to the browser 🚀.</p><h4>🔸 More React News Inside 👇</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*tQQHHUA7qUQpjb-A.png" /></figure><ul><li><a href="https://tanstack.com/start/latest"><strong>TanStack Start</strong></a> (a full-stack React framework powered by <a href="https://tanstack.com/router/latest">TanStack Router</a>) <a href="https://x.com/tannerlinsley/status/1942999038389006365"><strong>now supports Selective SSR</strong></a> — allowing you to choose <em>which routes use server-side rendering</em> and <em>which routes skip it</em> for browser-only dependencies like <strong><em>localStorage</em></strong>.</li><li><a href="https://react.dev/learn/react-compiler">The new <strong>React Compiler</strong> docs have officially landed</a> — now with their very own category <em>and</em> a dedicated reference page! Huge thanks to <a href="https://x.com/potetotes/status/1945554155055034748"><strong>Lauren</strong></a> 💯.</li><li><a href="https://x.com/jordanphughes/status/1945118391548735828"><strong>Untitled UI React</strong> is finally live</a> 🚀. It’s the world’s largest collection of open-source React components — built with Tailwind CSS and <a href="https://react-spectrum.adobe.com/react-aria/index.html">React Aria (UI accessibility toolkit)</a>. Just copy, paste, and build. <a href="https://untitledui.com/react/components"><strong>Check out the components</strong></a>.</li><li><a href="https://x.com/MUI_hq/status/1940489840501694634"><strong>Material UI </strong>(React UI tools)<strong> v7.2 is out</strong> 💯</a>! This release introduces <strong>Multiple Cascade Layers</strong> (CSS layer rules), letting you organize style priority into separate levels to simplify theming and ensure your <strong><em>sx prop</em> </strong>(inline styling)<strong> overrides work reliably</strong>.</li><li><a href="https://github.com/ant-design/ant-design/releases/tag/5.26.6"><strong>Ant Design</strong> (a React-based UI component library) <strong>has released version 5.26.6</strong></a>, featuring smoother inputs with the <a href="https://github.com/ant-design/ant-design/pull/54409">correct border color</a> and a more flexible Flex layout — <a href="https://github.com/ant-design/ant-design/pull/54399">no need to always pass children</a>.</li><li><a href="https://x.com/mantinedev/status/1947288333064773765"><strong>Mantine </strong>(React Component Library)<strong> v8.2 is out!</strong></a> The release includes <a href="https://mantine.dev/changelog/8-2-0/#container-grid-strategy"><strong>smarter layouts for <em>&lt;Container/&gt;</em></strong></a> <em>(You can now pass the strategy=”grid” attribute to the container, which lets certain sections stretch full screen, like banners or big headers)</em>, a handy <a href="https://mantine.dev/changelog/8-2-0/#use-selection-hook"><strong>new selection hook</strong></a> <em>(makes it easy to track which items are selected in a list or table)</em>, and <a href="https://mantine.dev/changelog/8-2-0/#source-edit-mode-in-richtexteditor"><strong>full HTML mode in the Rich Text Editor</strong></a> <em>(you can switch to raw code view and edit the HTML directly).</em></li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*e0KMQGfu4DwbDwVD.png" /></figure><blockquote><a href="https://anisrncore.substack.com/"><strong>SUBSCRIBE to the Newsletter on Substack to get the issues directly to your MAIL — Every Tuesday.</strong></a></blockquote><blockquote>💌 <a href="https://anisrncore.substack.com/">SUBSCRIBE this Newsletter (on Substack)</a> 🚀</blockquote><p>&lt;iframe src=”<a href="https://anisrncore.substack.com/embed">https://anisrncore.substack.com/embed</a>&quot; width=”480&quot; height=”320&quot; style=”border:1px solid #EEE; background:white;” frameborder=”0&quot; scrolling=”no”&gt;&lt;/iframe&gt;</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*e0KMQGfu4DwbDwVD.png" /></figure><h3>🩵 Today’s — Dev of the Week 🎖️</h3><p><a href="https://ruhul-info.vercel.app/"><strong>Ruhul Amin</strong></a>, a curious-minded developer with 7 years of programming experience — 5 in React and 2 in blockchain — is now diving deeper into a PhD, focused on blockchain.</p><p>He has developed and audited numerous smart contracts and decentralized applications (dApps), built a <a href="https://github.com/ruhulamin1398/Smart-Contract-Library"><strong>smart contract library</strong></a>, is writing a <a href="https://github.com/ruhulamin1398/Smart-Contract-Security-for-Developers-A-Guide-to-Auditing-and-Best-Practices">book on smart contract security</a>, and has led a <a href="https://github.com/ruhulamin1398/SecureDoc__AI_powered_Blockchain-Based-Document-Authentication">government-backed project to verify certificates using blockchain</a>.</p><p>He &amp; his team are currently building a <strong>Hybrid-Backed USD-Pegged Stablecoin Ecosystem</strong> that allows swapping between different types of tokens (like fiat-backed and crypto-backed), especially designed for banks looking to onboard their customers into crypto.</p><p>💬 <em>Need help with crypto or blockchain solutions? </em><a href="https://www.linkedin.com/in/theruhulamin/"><em>Reach out to Ruhul for expert guidance</em></a><em>.</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*-YSPyOy8X_0pPYHZ.png" /></figure><blockquote><strong>Ruhul subscribed to React20Bulletin and </strong><a href="https://www.linkedin.com/posts/theruhulamin_react-reactnative-devnewsletter-activity-7353454910912241664-IUM8?utm_source=share&amp;utm_medium=member_desktop&amp;rcm=ACoAACTSeaQBhT5gKLvTCnzx-bF4Gx1od8jqgSM"><strong>mentioned us on LinkedIn</strong></a><strong> — now he’s featured 🤝. </strong><a href="https://anisrncore.substack.com/p/dev-of-the-week"><strong><em>Follow the same steps to get into the newsletter!</em></strong></a></blockquote><blockquote>💌 <a href="https://anisrncore.substack.com/">SUBSCRIBE this Newsletter (on Substack)</a> 🚀</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*IONMY6MY2ldHeQDi.png" /></figure><h3>⚛️ All the Hot React Native Updates</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*aSXA3pH3sTpsTKJ5.png" /></figure><h4>🔹 React Native Screens Overhaul 🚀</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*GFidXk4QfpasqVQT.png" /></figure><p><a href="https://x.com/swmansion"><strong>Software Mansion</strong></a> has released <a href="https://x.com/swmansion/status/1945858293781450792"><strong>React Native Screens v4.13</strong></a>, which introduces <a href="https://github.com/software-mansion/react-native-screens/releases/tag/4.13.0"><strong>Native Bottom Tabs</strong></a> for both <strong>iOS and Android</strong>. These tabs work with <strong>both the New and Legacy Architecture</strong>, making them flexible for all kinds of projects. The feature is currently in <a href="https://github.com/software-mansion/react-native-screens/releases/tag/4.13.0"><strong>Alpha</strong></a>, so it’s still experimental — but ready for early adopters to test and give feedback. <a href="https://x.com/kacperkapusciak/status/1945862826213429483">A release that’s winning hearts 😍</a>. <strong>Kudos to </strong><a href="https://x.com/kafara_kacper"><strong>Kafara</strong></a><strong>, </strong><a href="https://x.com/maciekstosio"><strong>maciekstosio</strong></a><strong>, </strong><a href="https://x.com/kzzzf"><strong>Krzysztof</strong></a><strong> &amp; the whole team.</strong></p><p><a href="https://x.com/Baconbrix"><strong>Evan</strong></a> from the Expo team confirmed that <a href="https://x.com/Baconbrix/status/1945935781333275039"><strong>Native Bottom Tabs are coming to Expo Router</strong></a> soon for both platforms (Android &amp; iOS).</p><h4>🔹 Announcing Stable Unistyles 3.0 💥</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*_sUFl4PyX2RyZxm0.png" /></figure><p><a href="https://x.com/jpudysz/status/1942185645859848603"><strong>Jacek has announced the first stable release of Unistyles 3.0</strong></a>, featuring C++-powered StyleSheets and styling via <a href="https://github.com/mrousavy/nitro"><strong><em>react-native-nitro-modules</em></strong></a>, giving it native-like performance. <strong>More importantly, Unistyles 3.0’s </strong><a href="https://www.reactnativecrossroads.com/posts/introducing-unistyles-3"><strong>core highlight is Selective Updates</strong></a>, which check &amp; update only the affected styles (e.g., from theme changes or screen rotation) — so your app updates <strong>without any full re-renders</strong>.</p><p><strong>Unistyles 3.0 is designed for the </strong><a href="https://www.reactnativecrossroads.com/posts/introducing-unistyles-3"><strong>New Architecture only</strong></a>, and is compatible with <strong>React 19</strong>, <strong>React Native 0.75</strong>, and <strong>Expo SDK 52</strong>. 📅 Support for Unistyles 2.0 ends on <strong>December 31, 2025</strong>, with no patches released after that date.</p><h4>🔹 Announcing Ignite 11 — Bison 🔥</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*2lFfxgMDeSHJXLds.png" /></figure><p>The<strong> </strong><a href="https://infinite.red/"><strong>Infinite Red</strong></a><strong> </strong>team started the month by releasing<strong> </strong><a href="https://shift.infinite.red/announcing-ignite-11-bison-f2802a85f94d"><strong>Ignite 11, called “Bison.”</strong></a> This version now works <strong>only with the New Architecture</strong>, includes <strong>Expo SDK 53</strong>, and supports <a href="https://developer.android.com/about/versions/15/behavior-changes-15#edge-to-edge_enforcement"><strong>Android 15’s edge-to-edge enforcement</strong></a><strong> by Google</strong> — meaning app content now uses the full screen, including areas under the status bar. Also, you can now <strong>Bring Your Own State Management</strong> tool, replacing the default <a href="https://mobx.js.org/README.html"><strong>MobX</strong></a> setup.</p><p><strong><em>📝 Note:</em></strong><em> </em><a href="https://docs.infinite.red/ignite-cli/">Ignite is a React Native / Expo boilerplate (starter kit)</a> that’s been actively maintained since 2016, <a href="https://github.com/infinitered/ignite">with over 18K GitHub stars</a>.</p><h4>🔹 More React Native News Inside 👇</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*fwbUw4Jqh0Ak2RNY.png" /></figure><ul><li>Heads up, everyone: <a href="https://x.com/callstackio/status/1947265796633174308"><strong>10 days left</strong> until <strong>React Universe Conf tickets</strong> get pricier.</a> Late Birds batch drops Aug 1.</li><li><a href="https://x.com/grabbou">Mike, Callstack’s CTO</a>, shared that <a href="https://x.com/grabbou/status/1944809764543979555"><strong>Apple’s on-device AI is now in React Native</strong></a> 🚀. They’ve released a preview of <a href="https://www.callstack.com/blog/on-device-apple-llm-support-comes-to-react-native">@react-native-ai/apple</a>, a package that brings Apple Intelligence models — including a ~3B parameter model — right to users’ devices. It supports <a href="https://www.callstack.com/blog/on-device-apple-llm-support-comes-to-react-native">text generation</a>, <a href="https://www.callstack.com/blog/on-device-apple-llm-support-comes-to-react-native">streaming</a>, and more — all running locally.</li><li><a href="https://x.com/kraenhansen/status/1943286218705326479">Kraen Hansen</a>, <a href="https://www.callstack.com/blog/announcing-node-api-support-for-react-native">along with the Callstack team</a>, announced a new SDK, <a href="https://github.com/callstackincubator/react-native-node-api?tab=readme-ov-file"><strong><em>react-native-node-api</em></strong></a>, to support Node-API in React Native. Starting today, <a href="https://x.com/kraenhansen/status/1943286220504572355">any of your favorite <strong>Node.js</strong> packages can run in your React Native project</a> using this SDK.</li><li><a href="https://x.com/swmansion/status/1943330293315674351">Software Mansion</a> introduced <a href="https://www.npmjs.com/package/@expensify/react-native-wallet/v/0.1.5"><strong><em>react-native-wallet</em></strong></a>, built in collaboration with <a href="https://use.expensify.com/">Expensify</a>. It provides a <a href="https://blog.swmansion.com/introducing-react-native-wallet-90c1ee103d3e">React Native way to add payment cards to Apple Wallet and Google Wallet</a>, allowing users to complete payments without manually entering card details — just tap a button. It works on both <strong>iOS</strong> and <strong>Android</strong>, and supports a wide array of card providers like <strong>Visa</strong>, <strong>MasterCard</strong>, <strong>Amex</strong>, and <strong>Discover</strong>.</li><li><a href="https://x.com/swmansion/status/1947299922715283496">Software Mansion</a> launched <a href="https://play.google.com/store/apps/details?id=com.swmansion.privatemind&amp;pli=1"><strong>Private Mind</strong></a>, a React Native app built with <a href="https://docs.swmansion.com/react-native-executorch/docs/fundamentals/getting-started"><strong>React Native ExecuTorch</strong></a><strong>,</strong> which brings Meta’s on-device AI framework that can run <a href="https://docs.pytorch.org/docs/stable/index.html"><strong>PyTorch</strong></a> machine-learning models <strong>100% locally</strong> on your device. <a href="https://github.com/software-mansion-labs/private-mind">The source code is open</a>, so you can easily add it to your project.</li><li><a href="https://x.com/ziusko/status/1947563481630179521">Kiryl</a> from the Mergelo team released <a href="https://kirillzyusko.github.io/react-native-keyboard-controller/blog/keyboard-extensions"><strong>react-native-keyboard-controller v1.18.0</strong></a>, which now lets you bring your custom views inside the keyboard — meaning you can place custom UI (like a “Scan QR” button) directly above the keys.</li></ul><blockquote><a href="https://anisrncore.substack.com/"><strong>SUBSCRIBE to the Newsletter on Substack to get the issues directly to your MAIL — Every Tuesday.</strong></a></blockquote><blockquote>💌 <a href="https://anisrncore.substack.com/">SUBSCRIBE this Newsletter (on Substack)</a> 🚀</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*_o6b-q_xanOsnq6G.png" /></figure><h3>🎬 New Dev Content — Live?</h3><ul><li><a href="https://youtu.be/gBEZ9SYfFDU"><strong>Deploy TanStack Start in Less Than A Minute</strong> </a>— Jack Herrington breaks it down quickly. Don’t miss this!</li><li><a href="https://youtu.be/l9ov48v0M2M"><strong>Build a Full Stack mobile app in just 8 Hours (React Native, Expo, Clerk, Supabase)</strong></a> — by notJust․dev. Be sure to catch this!</li><li><a href="https://nikuscs.com/blog/06-tanstack-start-deep-dive/"><strong>Tanstack Start — A deep dive into THE React Framework</strong></a> — blog published by Pedro Martins.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*kedBn_wsAw6wNzUt.png" /></figure><h3>💼 React Jobs — Now Hiring 🔥</h3><ul><li>Frontend Engineer — React Native — Austin <strong>— </strong><a href="https://www.loman.ai/careers#:~:text=Frontend%20Engineer%20-%20React%20Native"><strong>Apply Here</strong></a></li><li>React Native Mobile Developer​/Remote — Dubai <strong>— </strong><a href="https://www.learn4good.com/jobs/online_remote/software_development/4354054955/e/"><strong>Apply Here</strong></a></li><li>Senior JavaScript Engineer (React/TypeScript) — Remote — <a href="https://careers.vitals.app/o/senior-javascript-engineer-remote"><strong>Apply Here</strong></a></li><li>Senior Full Stack Developer (TypeScript) — Remote — <a href="https://cosuno.jobs.personio.de/job/2146833?language=en%3Flanguage%3D&amp;display=en"><strong>Apply Here</strong></a></li></ul><blockquote><strong>Got a React or React Native job opening?</strong> <a href="https://x.com/anis_RNCore">Send it to me</a> <em>only</em> if it’s legit — I share authentic roles from trusted companies. No scams.</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*u2uH-GNFEKH-LvKZ.png" /></figure><h3>🤖 AI Updates — You’ll Love</h3><ul><li><a href="https://x.com/pelaseyed/status/1947283836997337199"><strong>Announcing Grok CLI</strong></a><strong> </strong>— an open-source AI agent that brings the power of <a href="https://x.ai/grok"><strong>Grok</strong></a><strong> </strong>(an <strong>AI assistant</strong> developed by xAI) directly into your terminal.</li><li><a href="https://x.com/cursor_ai/status/1943353195108901035"><strong>Grok 4</strong> is available in <strong>Cursor</strong> (an AI Code Editor)!</a></li><li><a href="https://x.com/cursor_ai/status/1940817965211177471"><strong>Cursor</strong> can now make to-do lists, search PRs, queue messages, and much more.</a></li><li><a href="https://x.com/o_kwasniewski/status/1944041135501922800"><strong>Introducing Zero AI</strong></a><strong> </strong>— an AI CLI that allows you to use <a href="https://x.ai/news/grok-4">Grok4</a>, <a href="https://claude.ai/">Claude</a>, <a href="https://gemini.google.com/app">Gemini</a>, and a lot more — crafted by <a href="https://x.com/o_kwasniewski">Oskar from CallstackIO</a>.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*3JnIPfKfQ6QJRYJ6.png" /></figure><h3>🤔 Pro Programming Tips</h3><ul><li><a href="https://x.com/ryanflorence/status/1944804096688435471">When you need to <strong>optimize something</strong>, you should be able to go DOWN a layer of abstraction.</a></li><li><a href="https://x.com/expo/status/1941857417404227623">If you’re starting a new <strong>Expo project</strong>, consider these 12 tips.</a></li></ul><blockquote><a href="https://anisrncore.substack.com/"><strong>SUBSCRIBE to the Newsletter on Substack to get the issues directly to your MAIL — Every Tuesday.</strong></a></blockquote><blockquote>💌 <a href="https://anisrncore.substack.com/">SUBSCRIBE this Newsletter (on Substack)</a> 🚀</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*gB0zjlTGouknGeap.png" /></figure><h3>🏕️ Extras You Shouldn’t Miss</h3><ul><li><a href="https://x.com/nuxt_js/status/1945251738711187493"><strong>Nuxt 4.0 released</strong></a><strong> </strong>— A smoother dev experience with smarter data fetching and better TypeScript support.<strong> </strong><a href="https://nuxt.com/blog/v4"><strong>Read the official blog.</strong></a></li><li><a href="https://x.com/kiwicopple/status/1944828082482758054"><strong>Supabase Drops 7 New Components</strong></a> — Fresh tools for faster builds and better UI.<strong> </strong><a href="https://supabase.com/blog/supabase-ui-platform-kit"><strong>Explore the update</strong></a>.</li><li><a href="https://x.com/opencutapp/status/1947033062493270416"><strong>OpenCut Alpha Is LIVE!</strong></a> — Import videos, edit timelines, and more — all in your browser. No watermarks, full privacy. <a href="https://opencut.app/"><strong>Try it now</strong></a>.</li></ul><blockquote>💌 <a href="https://anisrncore.substack.com/">SUBSCRIBE this Newsletter (on Substack)</a> 🚀</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*DBlQVOdhL19rOBWL.png" /></figure><h3>💟 Partner with React20Bulletin</h3><p>💟 <strong>Sponsor With Us </strong>→<strong> </strong><a href="https://anisrncore.substack.com/p/sponsor"><strong>Click here</strong></a></p><p>💼 <strong>Hire Our Dev Team</strong> → <a href="https://anisrncore.substack.com/i/167807220/hire-our-dev-team-idea-to-app"><strong>Click here</strong></a></p><p>💯 <strong>More about Newsletter/ Author</strong> → <a href="https://anisrncore.substack.com/about"><strong>Click here</strong></a></p><p>😍 <strong>Support us</strong> <strong>on</strong> → <a href="https://medium.com/@anisurrahmanbup"><strong>Medium</strong></a>, <a href="https://x.com/React20Bulletin"><strong>X (Twitter)</strong></a>, <a href="https://www.linkedin.com/in/anis-react20bulletin/"><strong>LinkedIn</strong></a><strong>,</strong> and <a href="https://bsky.app/profile/react20bulletin.bsky.social"><strong>🦋 Bluesky</strong></a>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*HClJRth6uVUP4t21.png" /></figure><blockquote><a href="https://anisrncore.substack.com/"><strong>SUBSCRIBE to the Newsletter on Substack to get the issues directly to your MAIL — Every Tuesday.</strong></a></blockquote><blockquote>💌 <a href="https://anisrncore.substack.com/">SUBSCRIBE this Newsletter (on Substack)</a> 🚀</blockquote><p><strong><em>🔹</em></strong><em> Thanks for subscribing to </em><a href="https://anisrncore.substack.com/"><strong>React20Bulletin</strong></a><em>. This post is public, so feel free to share it. ➜ </em><a href="https://anisrncore.substack.com/p/birth-of-react20bulletin-001?utm_source=substack&amp;utm_medium=email&amp;utm_content=share&amp;action=share&amp;token=eyJ1c2VyX2lkIjo5NDQwNDAwMCwicG9zdF9pZCI6MTUwOTI3OTc4LCJpYXQiOjE3NTM1MzAzODYsImV4cCI6MTc1NjEyMjM4NiwiaXNzIjoicHViLTMyNTMxNTAiLCJzdWIiOiJwb3N0LXJlYWN0aW9uIn0.v6rR2mny3FhtGyn7oHDagAIvRv0ismi-84QOfxG-u3s">Share</a></p><p><strong><em>🔹 Help shape the next issue — we’d love your thoughts! ➜ </em></strong><a href="https://anisrncore.substack.com/survey/3912689?token=">Give your Feedback!</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=bf4428cded73" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[ Welcome to React20Bulletin Newsletter — Why Subscribe?]]></title>
            <link>https://medium.com/@anisurrahmanbup/welcome-to-react20bulletin-newsletter-why-subscribe-808f04868074?source=rss-d463021d2ee9------2</link>
            <guid isPermaLink="false">https://medium.com/p/808f04868074</guid>
            <category><![CDATA[react]]></category>
            <category><![CDATA[react-native]]></category>
            <dc:creator><![CDATA[Anis  React20Bulletin]]></dc:creator>
            <pubDate>Sat, 19 Jul 2025 10:39:45 GMT</pubDate>
            <atom:updated>2026-02-05T20:13:24.493Z</atom:updated>
            <content:encoded><![CDATA[<h3>📨 Welcome to React20Bulletin Newsletter — Why Subscribe?</h3><h4>🚀 A top-notch newsletter bringing you the 20 best React and React Native updates every Tuesday — delivered straight to your inbox (email)</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*xr4UFwUYjmu6NbBgu3xL4g.png" /></figure><p>Hey <strong>React</strong> &amp; <strong>React Native</strong> folks!</p><p>It’s official! After months of planning, <a href="https://anisrncore.substack.com/"><strong>React20Bulletin</strong></a> launches <strong>Tuesday</strong>, July 22 🎉. <strong>20 React &amp; React Native news</strong>, delivered to your inbox (email) every <strong>Tuesday</strong>. <a href="https://anisrncore.substack.com/"><strong>Subscribe</strong></a> now (on <a href="https://anisrncore.substack.com/"><strong>Substack</strong></a>) to get it <strong>FREE</strong>!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*4_-2T8VGr0ECDK5uMYInxg.png" /></figure><h3>💌 Intro to React20Bulletin 🎉</h3><p><a href="https://anisrncore.substack.com/"><strong>React20Bulletin</strong></a> is a top-notch, <strong>beginner-friendly</strong> newsletter — the first of its kind — bringing you the <strong>20 best React </strong>and<strong> React Native updates</strong> every <strong>Tuesday</strong>, delivered straight to your inbox (email). It covers 🔻</p><ul><li><strong>Top 10</strong> News on <strong>React</strong> including Next.js, React Router, Vercel SDKs, <a href="https://ui.shadcn.com/">shadcn/ui</a>, Remix, Remotion, TanStack Router &amp; many more updates and</li><li><strong>Top 10</strong> News on <strong>React Native</strong> including Expo, OneJS, Software Mansion (Reanimated, Gesture Handler), CallstackIO (VisionOS, RNTL), MergeloIO (Vision Camera, Nitro Module) SDK updates, Skia &amp; many more.</li></ul><p><strong>🩵 Join thousands of devs staying connected ➙ </strong><a href="https://anisrncore.substack.com/"><strong>SUBSCRIBE</strong></a><strong> and stay updated.</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*rzWXCYrjfLnbSqSS.png" /></figure><h3>🔥 Why Subscribe? 🔥</h3><p>Subscribing to <a href="https://anisrncore.substack.com/"><strong>React20Bulletin</strong></a> is worthwhile because you’ll receive all of the following goodies <strong>every Tuesday</strong>, straight to your inbox (mail):</p><ul><li>⚛️<strong> Top 10 React news </strong>of the week</li><li>⚛️<strong> Top 10 React Native news </strong>of the week</li><li><strong>🤖 Top AI highlights </strong>of the week</li><li><strong>💼 Open React job </strong>opportunities</li><li>🔥<strong> Dev of the Week </strong>spotlight ➙ ❝<strong>You in Next News</strong>❞ 👇</li></ul><blockquote><a href="https://anisrncore.substack.com/p/dev-of-the-week"><strong><em>Dev of the week</em></strong></a><em> is a chance to make </em><strong><em>your Profile, SDK, Product, or Work go viral</em></strong><em> in front of thousands of developers through the </em><a href="https://anisrncore.substack.com/"><strong><em>React20Bulletin</em></strong></a><em> newsletter at </em><strong><em>100% free </em></strong><em>of cost 💟 </em><strong><em>(Details on next section 🔻🔻🔻)</em></strong></blockquote><p><strong>🩵 </strong>Why wait? <a href="https://anisrncore.substack.com/"><strong>Subscribe</strong></a><strong> now and be part of the momentum 🚀.</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*rzWXCYrjfLnbSqSS.png" /></figure><h3>🚀 How to be a → Dev Of The Week? 🎖️</h3><p><em>How can </em><strong><em>you</em></strong><em> be in the next news for 100% free?</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*_0T4sbaaYdXvm4SjIqM9ag.png" /></figure><p>If you’d like to be featured as <strong>Dev of the Week</strong> in the <a href="https://anisrncore.substack.com/"><strong>React20Bulletin</strong></a> next<strong> </strong>newsletter, follow these steps:</p><ul><li>Subscribe to the <a href="https://anisrncore.substack.com/"><strong>React20Bulletin</strong></a><strong> </strong>newsletter 🤝<strong>.</strong></li><li>Read the most recent newsletters.</li><li>Mention <a href="https://x.com/React20Bulletin"><strong>React20Bulletin</strong></a> and author <a href="https://x.com/anis_RNCore"><strong>Anis</strong></a> on <strong>X (Twitter)</strong>, and share how the newsletter helped expand your knowledge.</li></ul><h4>What will you get in return?</h4><ul><li>Each week, we’ll select one lucky developer from our subscriber list <strong>who posts their journey with </strong><a href="https://x.com/React20Bulletin"><strong>React20Bulletin</strong></a><strong> on </strong><a href="https://x.com/anis_RNCore"><strong>Twitter (X)</strong></a>. We’ll then spotlight that developer’s latest SDK or product in the <a href="https://anisrncore.substack.com/"><strong>React20Bulletin</strong></a> newsletter — shared with thousands of developers across the community 🚀</li></ul><p><strong>🩵 Interesting? SUBSCRIBE React20Bulletin:</strong> <a href="https://anisrncore.substack.com/">anisrncore.substack.com</a></p><blockquote><strong>🔥 We’ll make you — or your work — go viral.</strong> Just <a href="https://anisrncore.substack.com/"><strong>subscribe</strong></a> on <a href="https://anisrncore.substack.com/"><strong>Substack</strong></a>.</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*rzWXCYrjfLnbSqSS.png" /></figure><p>💟 <strong>Sponsor With Us </strong>→<strong> </strong><a href="https://anisrncore.substack.com/p/sponsor"><strong>Click here</strong></a></p><p>💼 <strong>Hire Our Dev Team</strong> → <a href="https://anisrncore.substack.com/i/167807220/hire-our-dev-team-idea-to-app"><strong>Click here</strong></a></p><p>💯 <strong>More about <em>React20Bulletin</em> Newsletter/ Author</strong> → <a href="https://anisrncore.substack.com/about"><strong>Click here</strong></a></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*rjTk_kU2b6VA8u2X.png" /></figure><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=808f04868074" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[React Native V0.74 — Stable is out ]]></title>
            <link>https://medium.com/@anisurrahmanbup/react-native-v0-74-stable-is-out-8943ea367217?source=rss-d463021d2ee9------2</link>
            <guid isPermaLink="false">https://medium.com/p/8943ea367217</guid>
            <category><![CDATA[android-development]]></category>
            <category><![CDATA[react-native]]></category>
            <category><![CDATA[react-native-release]]></category>
            <category><![CDATA[react-native-development]]></category>
            <category><![CDATA[ios-development]]></category>
            <dc:creator><![CDATA[Anis  React20Bulletin]]></dc:creator>
            <pubDate>Wed, 08 May 2024 19:32:44 GMT</pubDate>
            <atom:updated>2024-05-08T19:32:44.487Z</atom:updated>
            <content:encoded><![CDATA[<h3>React Native V0.74 — Stable is out 🚀</h3><p>Hi <strong>React Native </strong>Developers,</p><p>Exciting news in the world of React Native is that <strong>V0.74</strong> was released just a couple of days ago with over 1600 commits. The highlights are:</p><ul><li><strong>Yoga 3.0</strong></li><li><strong>New Architecture: Bridgeless by Default</strong></li><li><strong>New Architecture: Batched </strong><strong>onLayout Updates</strong></li><li><strong>Yarn 3 for New Projects</strong></li></ul><p>Let’s dive into each of the new highlights.</p><figure><img alt="" src="https://cdn-images-1.medium.com/proxy/1*pJQga189wcrMpV8J0chYxg.png" /></figure><h3>Yoga 3.0</h3><p>Let&#39;s understand first what <strong>yoga</strong> is in React Native.</p><h4>Yoga — the layout engine</h4><p>Yoga is an open-source <strong>layout engine</strong> developed by Meta. The engine which refers to <strong>how UI elements</strong> (such as buttons, text, images, etc.) are <strong>arranged</strong> and <strong>positioned</strong> within a user interface.</p><p>Yoga calculates these four for each UI element.</p><ol><li><strong>Positioning</strong></li><li><strong>Sizing</strong></li><li><strong>Alignment</strong></li><li><strong>Spacing</strong></li></ol><p>With Yoga, you can create <strong>responsive layouts</strong> that adapt to different screen sizes and orientations. It also implements a widely used concept called <strong>CSS Flexbox </strong>in React Native. So you already feel that yoga is the heart (♥︎) of React Native flexible UI.</p><h4>Yoga 3.0 — what’s new?</h4><p>In all previous versions of React Native, there were some incorrect layout behaviors. <strong>Yoga 3</strong> solved all of them. One of the most common issues was that the <strong>‘row-reverse’ </strong>style was not functioning properly.</p><p>Let’s look at the image below where the <strong>left</strong> one is from <strong>V0.73</strong> and the <strong>right</strong> one is from <strong>V0.74</strong>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*pJQga189wcrMpV8J0chYxg.png" /></figure><p>In the above image, we have a <strong>&lt;Container/&gt;</strong>, then inside it a <strong>&lt;Parent/&gt;</strong> component, then inside <strong>two &lt;Child/&gt;</strong> components.</p><p>We then applied this style in the <strong>&lt;Parent/&gt;</strong> component.</p><pre>// Style for &lt;Parent/&gt; component<br>style={{<br>      flexDirection: &#39;row-reverse&#39;,<br>      backgroundColor: &#39;dodgerblue&#39;,<br>      flex: 1,<br>      marginLeft: 100,<br>      marginRight: 20,<br>      marginVertical: 20,<br>      alignItems: &#39;center&#39;<br>}}</pre><p>Did you notice, that we added a <strong>marginLeft</strong> of <strong>100</strong> pixels for <strong>&lt;Parent/&gt;</strong>? Yeah, but see the output in React Native V0.73 (the left one) from the above image. It shows a 100 pixels margin on the <strong>right (not on the left)</strong> !! Okay, now let’s see the output of React Native V0.74 (the right one). Great, in V0.74 we see a perfect 100-pixel margin at <strong>left,</strong> and also two <strong>&lt;Child/&gt;</strong> components got <strong>reversed</strong> 🚀</p><p>So, in Yoga-2, if you apply a <strong>‘row-reverse’</strong> flex-direction with <strong>“margin”</strong> or <strong>“padding”</strong> or <strong>“border”</strong> in a component then the edges of that component also get flipped. But in Yoga-3 it has been solved perfectly 💯</p><p>Yoga-3 has brought some other important styling components that were missing in Yoga-2.</p><ul><li>&#39;space-evenly&#39; property for alignContent style</li><li>&#39;static&#39; property for position style</li></ul><h3><strong>New Architecture: Bridgeless by Default</strong></h3><h4>Old Architecture</h4><p>React Native previously used a <strong>bridge</strong> to communicate between JavaScript and native modules. The Modules are written in C++, Objective C, Java, or kotlin to access native features like cameras, sensors, etc. Unfortunately, the <strong>Bridge</strong> has some limitations.</p><p>One main limitation is that each time one layer communicates with another, it involves serializing (converting JS Object to JSON String) and deserializing (converting JSON String back to JS Object) data. Since the conversion takes time, this process adds a performance issue to the communication flow.</p><h4>New Architecture — performance booster</h4><p>The good news is that the React Native team was able to replace the bridge with an interface called <strong>JSI (JavaScript Interface)</strong>. It was written in C++ and it opens up all the native features available to your JS code, which means that you can call native methods without any data serialization or deserialization, making the app super fast.</p><h4>Remove OLD architecture dependencies</h4><p>JSI is the core part of New Architecture. To enable JSI (New Architecture) with its full power in our app, we need to first remove the app dependency from OLD <strong>bridge</strong> architecture. To do that, the React Native Team has introduced <strong>three pillars</strong> of New Architecture, which allow us to remove full dependency on the bridge.</p><ol><li><strong>TurboModules:</strong> It removed the app dependency on <strong>native calls</strong> from the bridge (released on V0.68)</li><li><strong>Fabric Renderer:</strong> It removed the app dependency on <strong>component rendering</strong> from the bridge (released on V0.68)</li><li><strong>Bridgeless Mode:</strong> It removed the app dependency on <strong>everything else</strong> (i.e: the rest of the React Native runtime: error handling, global event emitters, timers, and more) from the bridge (released on V0.73)</li></ol><h4>What is new in V0.74?</h4><p>From <strong>V0.74</strong>, once you enable the New Architecture, you will see that <strong>‘Bridgeless Mode’</strong> has been enabled <strong>automatically</strong>. However, the New Architecture itself is still not yet enabled by default.</p><p>When you enable New Architecture in your React Native app with <strong>V0.74</strong>, you will see these <strong>two lines</strong> like the below in your Metro Log:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*o1vN9WObY9GFSlp2f6lG1g.png" /></figure><p>That’s it 🚀. From React Native <strong>V0.74</strong>, you <strong>don’t need to enable Bridgeless mode manually</strong> after enabling New Architecture 💯</p><h3><strong>New Architecture: Batched </strong><strong>onLayout Updates</strong></h3><p>Another great news is that the React Native team not only made the New Architecture <strong>Bridgeless Mode</strong> the default, but they also improved this architecture to handle batched <strong>onLayout</strong> updates (executing multiple updates in a single rendering). This optimization enhances performance by minimizing layout-related computations during rendering.</p><h4>The “onLayout” props</h4><p>The onLayout prop in React Native is used to handle <strong>layout (position)</strong> changes for a component. When the layout of a component changes (due to mounting, resizing, rotation, or other factors), the onLayout callback function is triggered.</p><p>You can use this prop like below to <strong>perform actions</strong> based on the updated layout information.</p><pre>function App(){<br>  return (<br>      &lt;View<br>         onLayout={() =&gt; {<br>          console.log(&#39;Component has been invoked 🚀&#39;)<br>         }}<br>      /&gt;<br>   )<br>}</pre><h4>How “onLayout&quot; batch update works?</h4><p>Assume the component <strong>&lt;App/&gt;</strong> is as shown below, where each <strong>View</strong> triggers an <strong>onLayout</strong> callback function when mounted.</p><pre>function App() {<br> const [state1, setState1] = useState(false)<br> const [state2, setState2] = useState(false)<br> const [state3, setState3] = useState(false)<br><br> console.log(&#39;✅ COMPONENT RE-RENDERED .....&#39;)<br><br> return (<br>  &lt;View&gt;<br>   &lt;View<br>    onLayout={() =&gt; {<br>     console.log(&#39;FIRST View invoked&#39;)<br>     setState1(true) // Update state1 when the View mounts<br>    }}&gt;&lt;/View&gt;<br><br>   &lt;View<br>    onLayout={() =&gt; {<br>     console.log(&#39;SECOND View invoked&#39;)<br>     setState2(true) // Update state2 when the View mounts<br>    }}&gt;&lt;/View&gt;<br><br>   &lt;View<br>    onLayout={() =&gt; {<br>     console.log(&#39;THIRD View invoked&#39;)<br>     setState3(true) // Update state3 when the View mounts<br>    }}&gt;&lt;/View&gt;<br>  &lt;/View&gt;<br> )<br>}</pre><p>Now, in React Native <strong>V0.73</strong>, you will see an output like below 👇</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/996/1*i3Ahq2Dc1OwVXY-gfhLSCQ.png" /></figure><p>Did you notice that, on each execution of the <strong>“onLayout”</strong> callback, it re-renders the whole component? Yeah, it is not expected.</p><p>Now, let’s see the output in React Native <strong>V0.74</strong> with enabling <strong>New Architecture</strong> 👇</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*6YXc49M7CsVZFNeZh1N6yQ.png" /></figure><p>Amazing performance 🔥. The component got re-rendered only once for all 3 <strong>“onLayout”</strong> callback execution.</p><p>A good summary in the below image on <strong>“onLayout” </strong>batch update<strong> 👇</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*fMOuEt9ovEuLiZtKcbwvFg.png" /></figure><h3><strong>Yarn 3 for New Projects</strong></h3><p><strong>Yarn 3</strong> is now the default JavaScript package manager for new projects initialized with React Native Community CLI. This replaces Yarn Classic <strong>(1.x)</strong>, which was deprecated and previously used as the default.</p><p>Yarn 3 speeds up the process of installing and updating dependencies and optimizes how dependencies are stored.</p><h3>That’s it 🙌</h3><p>React Native version <strong>0.74</strong> introduced significant improvements in component layout, and architecture, batched onLayout updates, and integration with Yarn 3.</p><h3>All Latest React Native News 🚀</h3><p>I’m writing on all the latest <strong>React Native news</strong> on my Twitter account. You can follow me there &amp; keep yourself updated with this highly evolving space. <strong>(My Twitter account: </strong><a href="https://twitter.com/anis_RNCore"><strong>Anis</strong></a><strong>).</strong></p><p>I’m also publishing my deep R&amp;D on React Native&#39;s latest releases of different SDKs. <a href="https://github.com/anisurrahman072/React-Native-SDK-Research"><strong>(LINK: https://github.com/anisurrahman072/React-Native-SDK-Research)</strong></a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=8943ea367217" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[React Native Screens V3.30: What’s New!]]></title>
            <link>https://medium.com/@anisurrahmanbup/react-native-screen-v3-30-whats-new-15466474fc0a?source=rss-d463021d2ee9------2</link>
            <guid isPermaLink="false">https://medium.com/p/15466474fc0a</guid>
            <category><![CDATA[react-native-screen]]></category>
            <category><![CDATA[react-native]]></category>
            <category><![CDATA[react-native-development]]></category>
            <category><![CDATA[react-native-gesture]]></category>
            <dc:creator><![CDATA[Anis  React20Bulletin]]></dc:creator>
            <pubDate>Wed, 24 Apr 2024 05:39:18 GMT</pubDate>
            <atom:updated>2024-05-08T19:35:40.184Z</atom:updated>
            <content:encoded><![CDATA[<p>Hey <strong>React Native </strong>Developers,</p><p>I’m thrilled to share some exciting news from <strong>Software Mansion</strong>! 🚀 In the ever-evolving world of React Native, they’ve made remarkable strides. Last month, they unveiled <strong>react-native-screens</strong> version 3.30, and it comes with a groundbreaking feature: <strong>“Custom Screen Transitions Based on Gesture.”</strong></p><p>In today’s newsletter, we’ll dive into the code and explore how we can harness this powerful feature in our React Native apps.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*e3lUuSiZgs_K3By3hBhNCg.gif" /></figure><p>Before we delve further, let’s explore the essential groundwork of React Native Screens.</p><h3>The React-Native-Screens library</h3><p>When building React Native applications, <strong>effective navigation</strong> is essential. <strong>React Native Screens</strong>, developed by Software Mansion, provides <strong>native navigation primitives</strong> specifically tailored for React Native apps. These primitives correspond to <strong>native components</strong> offered by your phone’s operating system. By leveraging these components, <strong>React-native-screens</strong> enhances performance and ensures that your app operates seamlessly.</p><p>However, it’s important to note that <strong>React Native Screens</strong> isn’t intended to be used as a standalone library for handling navigation independently. Instead, it serves as a dependency for <strong>full-featured</strong> navigation libraries.</p><p>Some of the most popular full-featured navigation libraries are:</p><ul><li><a href="https://github.com/react-navigation"><strong>react-navigation</strong></a> (Most popular for bare React Native apps)</li><li><a href="https://github.com/wix/react-native-navigation"><strong>react-native-navigation</strong></a> (Created by Wix)</li></ul><p>We will use <a href="https://github.com/react-navigation"><strong>react-navigation</strong></a><strong> </strong>for this newsletter. Let’s get cooking with it! 🍟.</p><h3><strong>Custom</strong> screen transitions based on Gesture</h3><p>From now on, in React Native apps, developers can apply a screen transition effect based on users’ gestures (like swipe up, swipe left, etc) while going back to the previous screen. To make this feature ready, three open-source teams from Software Mansion came to the table.</p><ol><li>react-native-reanimated</li><li>react-native-screens</li><li>react-native-gesture-handler</li></ol><p>All the teams have published their dependencies for this feature in their latest release. Just “react-native-reanimated ” team&#39;s latest release is in pre-release V3.9.0-rc.0.</p><p>In the next section, we will explore the necessary additions or upgrades to our app, enabling the implementation of this feature.</p><h3>Install with React-Navigation</h3><p>To enable <strong>Custom screen transitions</strong> with gesture let’s install the following packages.</p><ul><li>First, install React Navigation:</li></ul><pre>npm install @react-navigation/native</pre><ul><li>Then install React Native Gesture Handler, React Native Screens (Latest version is important) &amp; its dependencies:</li></ul><pre>npm install react-native-gesture-handler react-native-screens react-native-safe-area-context</pre><ul><li>Finally, install the pre-release version (V3.9.0-rc.0) of “React Native <strong>Reanimated</strong>”. Or if you already installed it before then upgrade it to “3.9.0-rc.0”.</li></ul><pre>npm install react-native-reanimated@3.9.0-rc.0</pre><p>You can check the reanimated release note from here <a href="https://github.com/software-mansion/react-native-reanimated/releases/tag/3.9.0-rc.0">(Change Log of reanimated 3.9.0-rc.0)</a>.</p><h3>Code Example</h3><p>To enable custom screen transitions based on gestures, we need to modify our navigation file (the file that declares the names of each screen to navigate). We will use <strong>“App.js”</strong> as our navigation file in this example.</p><ol><li>We have to import <strong>“createNativeStackNavigator”</strong> from <strong>“react-native-screens/native-stack”</strong> instead of <strong>“@react-navigation/native-stack”</strong>. They both provide the same functionalities on navigation but “react-native-screens/native-stack” provides an extra functionality for handling <strong>Custom screen transitions</strong>.</li><li>We need to wrap the &lt;<strong>NavigationContainer /&gt;</strong> component by using <strong>&lt;GestureDetectorProvider /&gt;</strong> from <strong>“react-native-screens/gesture-handler”</strong>. The GestureDetectorProvider enables you to recognize and handle various gestures (like swipes, pinches, rotations, etc.) in your React Native app.</li><li>Finally, wrap your whole app by using <strong>&lt;GestureHandlerRootView /&gt; </strong>from <strong>“react-native-gesture-handler”</strong> as it allows your app to catch all touch events.</li></ol><p>The imports should look like below in “App.js”:</p><pre>// Imports in &quot;App.js&quot;<br>import { NavigationContainer } from &#39;@react-navigation/native&#39;<br>import { GestureHandlerRootView } from &#39;react-native-gesture-handler&#39;<br>import { createNativeStackNavigator } from &#39;react-native-screens/native-stack&#39;<br>import { GestureDetectorProvider } from &#39;react-native-screens/gesture-handler&#39;<br>import { ScreenTransition } from &#39;react-native-reanimated&#39;</pre><p>As we have imported all dependencies, now let’s do all the wrapping with these imported components:</p><pre>// Imports...<br><br>// Build the stack for screens<br>const Stack = createNativeStackNavigator()<br><br>// Build App function<br>function App() {<br>  return (<br>    &lt;GestureHandlerRootView style={styles.container}&gt;<br>      &lt;GestureDetectorProvider&gt;<br>        &lt;NavigationContainer&gt;<br>          &lt;Stack.Navigator&gt;<br>            &lt;Stack.Screen name=&quot;Home&quot; component={Home} /&gt;<br>            &lt;Stack.Screen name=&quot;ScreenA&quot; component={ScreenA} /&gt;<br>            &lt;Stack.Screen name=&quot;ScreenB&quot; component={ScreenB} /&gt;<br>          &lt;/Stack.Navigator&gt;<br>        &lt;/NavigationContainer&gt;<br>      &lt;/GestureDetectorProvider&gt;<br>    &lt;/GestureHandlerRootView&gt;<br>  );<br>}</pre><p>Let’s recap what we did in the above navigation file. The top component is now <strong>&lt;GestureHandlerRootView /&gt;</strong>, which detects all touch events in your app. The next component is <strong>&lt;GestureDetectorProvider /&gt;</strong>, responsible for identifying whether the touch corresponds to a gesture (such as swipes, pinches, rotations, etc.). After that, we have our <strong>&lt;NavigationContainer /&gt;</strong> component.</p><p>That’s it! You’ve enabled gesture action handling power in your React Native app. Now it’s time to apply some “go back” transitions to each screen, as shown below:</p><pre>// Imports...<br><br>// Build the stack for screens...<br><br>// Build App function<br>function App() {<br>  return (<br>    &lt;GestureHandlerRootView style={styles.container}&gt;<br>      ......<br>        &lt;Stack.Screen name=&quot;Home&quot; component={Home} /&gt;<br>        &lt;Stack.Screen name=&quot;ScreenA&quot; component={ScreenA} options={{<br>            goBackGesture: &#39;twoDimensionalSwipe&#39;<br>          }}<br>        /&gt;<br>        &lt;Stack.Screen name=&quot;ScreenB&quot; component={ScreenB} options={{<br>            goBackGesture: &#39;swipeDown&#39;<br>          }}<br>        /&gt;<br>      ......<br>    &lt;/GestureHandlerRootView&gt;<br>  );<br>}</pre><p>We used the “<strong>twoDimensionalSwipe</strong>” gesture for “ScreenA” &amp; “<strong>swipeDown</strong>” gesture for “ScreenB”. You are all set 🚀.</p><p>For your information, below are all the available gestures from <strong>React Native Screens</strong>:</p><ul><li>swipeRight</li><li>swipeLeft</li><li>swipeUp</li><li>swipeDown</li><li>verticalSwipe</li><li>horizontalSwipe</li><li>twoDimensionalSwipe</li></ul><p>Now let’s create the <strong>“Home”</strong> screen (component) to navigate to “ScreenA” &amp; “ScreenB”. The “Home” screen will be like the below:</p><pre>// Imports ...<br><br>// Build &quot;Home&quot; screen (component) <br>export default function Home({ navigation: { navigate } }) {<br>  return (<br>    &lt;View&gt;<br>      {/* GO TO SCREEN A */}<br>      &lt;TouchableOpacity onPress={() =&gt; navigate(&quot;ScreenA&quot;)}&gt;<br>        &lt;Text&gt; ScreenA &lt;/Text&gt;<br>      &lt;/TouchableOpacity&gt;<br><br>      {/* GO TO SCREEN B*/}<br>      &lt;TouchableOpacity onPress={() =&gt; navigate(&quot;ScreenB&quot;)}&gt;<br>        &lt;Text&gt; ScreenB &lt;/Text&gt;<br>      &lt;/TouchableOpacity&gt;<br>    &lt;/View&gt;<br>  );<br>}</pre><p>Design your screens (components) ScreenA and ScreenB. Reload your app, navigate from the Home screen to <strong>“ScreenA”</strong>, and then swipe in any direction as we’ve set up <strong>“twoDimensionalSwipe”</strong> for ScreenA. For <strong>“ScreenB”</strong>, perform a swipe down, as we’ve configured <strong>“swipeDown”</strong> for it. You’ll observe an effect like the one shown below: 👇</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*e3lUuSiZgs_K3By3hBhNCg.gif" /></figure><h3>That’s it 🙌</h3><p>In the latest <strong>React Native screens V3.30</strong>, a notable feature has been introduced: screen transition animations for <strong>“go back”</strong> gestures. This enhancement allows smoother and more visually appealing transitions when navigating between screens.</p><h3>All Latest React Native News 🚀</h3><p>I’m writing on all the latest <strong>React Native news</strong> on my Twitter account. You can follow me there &amp; keep yourself updated with this highly evolving space. <strong>(My Twitter account: </strong><a href="https://twitter.com/anis_RNCore"><strong>Anis</strong></a><strong> for React Native)</strong></p><p>I’m also publishing my deep R&amp;D on React Native’s latest releases of different SDKs. <a href="https://github.com/anisurrahman072/React-Native-SDK-Research"><strong>(LINK: https://github.com/anisurrahman072/React-Native-SDK-Research)</strong></a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=15466474fc0a" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[React Native — Testing (Ultimate Guide)]]></title>
            <link>https://medium.com/@anisurrahmanbup/react-native-testing-ultimate-guide-219a5e7ea5dc?source=rss-d463021d2ee9------2</link>
            <guid isPermaLink="false">https://medium.com/p/219a5e7ea5dc</guid>
            <category><![CDATA[testing]]></category>
            <category><![CDATA[react-native]]></category>
            <category><![CDATA[component-testing]]></category>
            <category><![CDATA[jest]]></category>
            <dc:creator><![CDATA[Anis  React20Bulletin]]></dc:creator>
            <pubDate>Mon, 11 Dec 2023 17:19:33 GMT</pubDate>
            <atom:updated>2024-02-01T16:32:48.115Z</atom:updated>
            <content:encoded><![CDATA[<h3>React Native — UI Testing (Ultimate Guide)</h3><h4>A comprehensive guide to React Native Component Testing.</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*v-mekN6hCmlHTruW1UruLA.png" /></figure><p>Over the course of a month, I meticulously crafted this comprehensive guide on testing for <strong>React Native</strong> applications. Each code snippet included in this article was initially <strong><em>executed successfully</em></strong> on my MacBook, ensuring their reliability.</p><p>This article serves as an all-encompassing resource on <strong>TESTING</strong>, covering a wide array of topics such as <strong>component testing</strong>, <strong>mocking</strong>, <strong>provider</strong> tests, <strong>fireEvent</strong>, and <strong>waitFor</strong> asynchronous operations, among others. It is designed to equip you with a thorough understanding of testing a <strong>React Native app</strong>, from getting started and setting up configurations, to troubleshooting potential errors.</p><p><strong>🔥 I have published an In Depth “React Native Advanced Guide Book” which secured ≈1000 GitHub STAR. </strong><a href="https://github.com/anisurrahman072/React-Native-Advanced-Guide"><strong>(Free Book Link)</strong></a></p><p>Let’s look at the topics that we will learn from this article.</p><ol><li><a href="#9363">Types of React Native Testing</a></li><li><a href="#85a6">Types of JavaScript Testing</a></li><li><a href="#195c">Tools for React Native Testing</a></li><li><a href="#b8de">Some Testing Libraries (Confusing names)</a></li><li><a href="#b3ad">When to apply Component Testing ?</a></li><li><a href="#6f89">React Native Testing Library (RNTL)</a></li><li><a href="#4512"><strong>Setup JEST config (for RNTL)</strong></a></li><li><a href="#79fa">Common Error in JEST config — ES6/Ts/cjs/mts</a></li><li><a href="#9c92">Command to run a test file</a></li><li><a href="#6955">React Native Testing Library (RNTL) APIs</a></li><li><a href="#cb64"><strong>🪵 RNTL API — render()</strong></a></li><li><a href="#5016">🐠 TEST Component with Provider — by render() API</a></li><li><a href="#b59b">🐠 “queries” option — render() API</a></li><li><a href="#c21d">🐠 “update&quot; option — render() API</a></li><li><a href="#40ef">🐠 “debug&quot; option — render() API</a></li><li><a href="#4a07"><strong>🪵 RNTL API — userEvent()</strong></a></li><li><a href="#9891">🐠 Example of FireEvent() API</a></li><li><a href="#d375"><strong>🪵 RNTL API — waitFor()</strong></a></li><li><a href="#0879"><strong>What is Mocking ?</strong></a></li><li><a href="#810e">🍁 Difference between jest.fn() &amp; jest.mock()</a></li><li><a href="#aaf8">🍁 How to Mock a Real Function (by jest.fn()) ?</a></li><li><a href="#22c1">🍁 How to Mock a Native Module (by jest.mock())?</a></li><li><a href="#f62f">🍁 Another example of Native Module Mocking ( jest.mock() )</a></li><li><a href="#47a6">Some Advanced Share about RNTL</a></li><li><a href="#dd6e">Differentiating between host and composite elements</a></li><li><a href="#a69e">🚀 Intro to E2E Testing</a></li></ol><blockquote>Let’s get started with RN — TESTING 🚀</blockquote><h3>Introduction to Testing in React Native</h3><p>In React Native, testing is important to prevent fragile programming and ensure that your code continues to work in the future. You can use different automated ways to ensure your app works as expected, ranging from static analysis to end-to-end tests. Writing testable code is intertwined with writing clean, modular code.</p><h3>Types of React Native Testing</h3><p>For practical reasons, we can distinguish <strong>React Native testing</strong> into these <strong>two</strong> parts:</p><ol><li><strong>JavaScript Testing — </strong>We mainly use the <strong>Jest</strong> framework to test our JavaScript code. When we work with React Native, we can group our tests into <strong>unit</strong> and <strong>integration</strong> tests. However, these two groups are not very different, so we <strong>do not need to separate them for practical purposes</strong>. We can just remember them so that we can comprehend them clearly. In the next section, we will see how many types of testing <strong><em>JavaScript Testing</em></strong> includes.</li><li><strong>End-to-End app Testing — </strong>It typically verifies the entire application from start to end to <strong>ensure the user flows work correctly</strong>, this can include testing a user can sign up, login, perform activities, navigate to different pages and log out from an application. These tests give the most confidence because they’re pretty much a <strong>robot</strong> running your app on a device. We perform <strong>E2E tests</strong> using <strong>Detox</strong>, <strong>Appium</strong>, or any other mobile testing framework that we know.</li></ol><p><strong><em>NOTE: </em></strong><em>Because most of your business code lives in JS, it makes sense to focus your efforts there.</em></p><p>Below, we see how the <strong>testing flow (pyramid)</strong> works. Testing starts with <strong>Static Analysis</strong> &amp; ends with <strong>End-to-End</strong> test.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*s0tBArqx38hcvCEkCNiruA.png" /><figcaption><strong>Testing Flow To Maintain </strong>(Starts with <strong>Static Analysis</strong> &amp; ends with <strong>E2E test</strong>)</figcaption></figure><p><strong><em>NOTE:</em></strong> <em>The main focus of this article is to dive you into the second part of Pyramid (</em><strong><em>JavaScript Testing</em></strong><em>).</em></p><h3>Types of JavaScript Testing</h3><p>We can split <strong>JavaScript Testing</strong> into these parts so that we can understand each step easily.</p><ol><li><strong>Unit testing</strong>: It typically focuses on verifying the functions works correctly, such as providing inputs to a function and checking its output against expected results.</li><li><strong>Component testing</strong>: It focuses on verifying an individual component renders correctly and behaves as expected based on the provided inputs to it.</li><li><strong>Integration testing</strong>: It tests how multiple components interact with each other, generally involves rendering multiple components and requires external dependencies, services or APIs. It is required to <strong>mock</strong> these for tests.</li><li><strong>Snapshot testing</strong>: It captures a snapshot of the rendered output of a component and compares it to previous saved snapshot to detect visual changes. It should be used with in combination with <strong>unit</strong> and <strong>component</strong> testing to ensure comprehensive coverage of an application.</li></ol><h3>Tools for React Native Testing</h3><ul><li><strong>Static Analysis:</strong> Flow, eslint</li><li><strong>JavaScript Test:</strong> Jest, Mocha, ava</li><li><strong>Component Testing:</strong><em> </em>React Native Testing Library by CallStack</li><li><strong>Webdriver Test (End to end test):</strong> Detox, Appium</li></ul><h3>Some Testing Libraries (Confusing names)</h3><p>I’m giving you some testing libraries and their creators or users. You may already be confused by the almost identical names of different libraries in the JS testing world.</p><ul><li><strong>react-testing-library:</strong> It is used for React web <a href="https://github.com/testing-library/react-testing-library"><em>react-testing-library</em></a><em> </em>which was created by<em> </em><strong>Kent C. Dodds</strong>.</li><li><strong>react-test-renderer:</strong> Created by meta &amp; they use it for testing <a href="https://www.npmjs.com/package/react-test-renderer"><em>https://www.npmjs.com/package/react-test-renderer</em></a>. Also, <strong><em>react-native-testing-library (RNTL) </em></strong>has <strong>peerDependencies</strong> listing for it.</li><li><strong>react-native-testing-library(RNTL):</strong> Created by <strong>CallStack</strong> on top of <strong><em>react-test-renderer</em></strong> &amp; they use it for testing React Native Components <a href="https://github.com/callstack/react-native-testing-library"><em>https://github.com/callstack/react-native-testing-library</em></a>.</li><li><strong>jest-native:</strong> It is used with <strong><em>JEST</em></strong> &amp; <strong><em>react-native-testing-library</em> . </strong>Use it for additional JEST matchers <a href="https://github.com/testing-library/jest-native"><em>https://github.com/testing-library/jest-native</em></a>.</li></ul><h3>When to apply Component Testing ?</h3><p>React Native <strong>Component Testing</strong> is a way of verifying the behavior and appearance of your React Native components in isolation from their dependencies. It can help you ensure that your components work as expected, follow the best practices, and are easy to maintain.</p><p>Some scenarios are below where React Native<strong> Component Testing can play a vital role</strong>.</p><ul><li>When you want to test the <strong>rendering</strong> and <strong>interaction</strong> of your components <strong>without mocking the native modules</strong> or <strong>using a device emulator</strong>.</li><li>When you want to test your components across <strong>different platforms</strong> and <strong>configurations</strong>. For example, you can use Jest’s <strong>platform-specific extensions to run different tests for iOS and Android</strong>, or use its configuration options to set up different environments or presets for your tests.</li><li>When you want to <strong>test your components with different data and props</strong>. For example, you can use <strong>Jest’s data-driven testing feature</strong> to run the same test with different inputs, or <strong>use its </strong><strong>mock functions<em> </em></strong>to simulate the props that your component receives from its parent.</li><li>When you want to <strong>test your components with different users and roles</strong>. For example, you can use Jest’s context feature to provide different values for global variables or constants that affect your component’s behavior, or use its <strong><em>spy functions to monitor</em></strong> how your component interacts with other modules or functions.</li><li>When you want to <strong>test your components with different themes and styles</strong>. For example, you can use Jest’s <strong>setupFiles</strong> option in <strong>JEST config</strong> to import a global style sheet or a theme provider for your tests, or use its expect.extend feature to create <strong>custom matchers</strong> for testing the appearance of your component.</li></ul><blockquote>Let’s get started with JS (Component) Testing</blockquote><h3>React Native Testing Library (RNTL)</h3><p>The React Native Testing Library (RNTL) is a lightweight solution for testing React Native components created by <strong>CallStack</strong>. It provides light utility functions on top of react-test-renderer, in a way that encourages better testing practices. Its primary guiding principle is:</p><p><strong><em>NOTE: </em></strong><em>The more your tests resemble the way your software is used, the more confidence they can give you.</em></p><h4>Install RNTL</h4><p>As from React native version 0.38, the project will have a default <strong>Jest</strong> setup with <strong>react-test-renderer</strong> included when you create the react-native project. Just make sure that your <strong>react-test-renderer</strong> version matches exactly your <strong>react</strong> version in <strong>package.json</strong> file.</p><p>To install <strong>RNTL</strong>, open a terminal in your project’s folder and run this below command.</p><pre>yarn add - dev @testing-library/react-native</pre><p>In order to use additional React Native-specific <strong>Jest matchers</strong> from @testing-library/jest-native package add it to your project by this below command.</p><pre>yarn add - dev @testing-library/jest-native</pre><p>Then add this additional <strong>Jest matcher </strong>to your jest tests by using setupFilesAfterEnv option in your Jest configuration. Jest configuration is usually located either in package.json under <strong>&quot;jest&quot;</strong> key like below or in a <strong>jest.config.js</strong> file in your project root directory.</p><pre>{<br>  &quot;preset&quot;: &quot;react-native&quot;,<br>  &quot;setupFilesAfterEnv&quot;: [&quot;@testing-library/jest-native/extend-expect&quot;]<br>}</pre><p>My <strong>package.json</strong> looks like below with additional <strong>Jest matcher </strong>config.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*KptsLb335zj-onET-V2fkg.png" /><figcaption><strong>package.json</strong> (only last part given here)</figcaption></figure><h3>Setup JEST config (for RNTL)</h3><p>We learned how to add <strong>JEST</strong> configuration for <strong>React Native Testing Library (RNTL)</strong> in either the <strong><em>package.json</em></strong> file or the <strong><em>jest.config.js</em></strong> file. Now let’s look at all the important options of JEST that we can set optionally along with <strong><em>preset</em></strong> or <strong><em>setupFilesAfterEnv</em></strong> in JEST configuration.</p><h4><strong>🧩 “preset”</strong></h4><p>jest-expo preset is used for testing React Native projects created using Expo, otherwise it would be react-native. Example like below:</p><pre>&quot;preset&quot;: &quot;react-native&quot;</pre><h4><strong>🧩</strong> <strong>“setupFiles”</strong></h4><p>This option is used to specify a module that should be executed <strong><em>before any tests</em></strong> run, such as <strong><em>setting up the test data</em></strong> or <strong><em>mocking</em></strong> external <strong><em>components</em></strong>, <strong><em>Native Modules</em></strong>, <strong><em>dependencies</em></strong>, <strong><em>services</em></strong> or <strong><em>APIs</em></strong>. Example like below:</p><pre>&quot;setupFiles&quot;: [<br>     &quot;./src/mock/api&quot;,<br>     &quot;./src/mock/services&quot;,<br>  ]</pre><h4><strong>🧩</strong> <strong>“setupFilesAfterEnv”</strong></h4><p>This option is used to set up additional testing libraries such as @testing-library/jest-native. Example like below:</p><pre>&quot;setupFilesAfterEnv&quot;: [&quot;@testing-library/jest-native/extend-expect&quot;]</pre><h4><strong>🧩</strong> “moduleFileExtensions”</h4><p>This option is used to specify the file extensions that should be looked for when running tests. For example, if you have test files with the extensions <strong>“.ts”, “.tsx”, “.js”, “.jsx”, “.json”</strong>, and <strong>“.node”</strong>, you can specify them in the “moduleFileExtensions” option like this:</p><pre>&quot;moduleFileExtensions&quot;: [<br>  &quot;ts&quot;,<br>  &quot;tsx&quot;,<br>  &quot;js&quot;,<br>  &quot;jsx&quot;,<br>  &quot;json&quot;,<br>  &quot;node&quot;<br>]</pre><p>This option is useful for React Native projects that use <strong>TypeScript</strong> or other languages that <strong>need to be transpiled before running</strong>. It also helps Jest to recognize different file types and handle them accordingly. For example, Jest will use <strong><em>“ts-jest”</em></strong> to transform TypeScript<strong> files</strong> and <strong><em>“jest-environment-jsdom”</em></strong> to provide a browser-like environment for testing.</p><h4><strong>🧩</strong> <strong>“moduleNameMapper”</strong></h4><p>The option <em>“moduleNameMapper”</em> is used to tell Jest <strong>how to find the files that you import in your code</strong>. Sometimes, you may use shortcuts or aliases to import files, for example, instead of writing:</p><pre>import { Button } from &quot;../../components/Button&quot;;</pre><p>You may write:</p><pre>import { Button } from &quot;components/Button&quot;;</pre><p>This makes your code shorter and cleaner, but Jest may not know where to find the file <strong>“components/Button”</strong>. To fix this, you can use the option <strong>“moduleNameMapper”</strong> to map the <strong>shortcut</strong> or <strong>alias</strong> to the <strong>actual file path</strong>. For example, you can write:</p><pre>&quot;moduleNameMapper&quot;: {<br>  &quot;^components/ (.*)$&quot;: &quot;&lt;rootDir&gt;/src/components/$1&quot;<br>}</pre><p>This means that <strong>Jest will replace any import</strong> that <strong>starts with “components/”</strong> with <strong>“&lt;rootDir&gt;/src/components/”</strong>. For example, <strong><em>“components/Button”</em></strong> will become <strong><em>“&lt;rootDir&gt;/src/components/Button”</em></strong>. You can use any regular expression to match the shortcut or alias, and use <strong>“$1”</strong>, <strong>“$2”</strong>, etc. to refer to the captured groups. You can also map different shortcuts or aliases to <strong>different file paths</strong> by using more lines.</p><h4><strong>🧩</strong> <strong>“transformIgnorePatterns”</strong></h4><p>The option <strong><em>“transformIgnorePatterns”</em></strong> is used to tell Jest which files it should not change before testing them. Sometimes, Jest needs to change some files, for example, if they use a different language or syntax than JavaScript. <strong>By default, Jest will not change any files in the “node_modules” directory</strong>, because they are usually already written in JavaScript. But sometimes, you may need to change some of them, for example, if they use <strong>TypeScript</strong> or <strong>ES6 syntax</strong>. To do that, you can use a special code to match the files that you want to change, and use a <strong>“!”</strong> sign to exclude the ones that you don’t. For example:</p><pre>&quot;transformIgnorePatterns&quot;: [<br>  &quot;/node_modules/ (?! (react-native|react-native-cookies)/)&quot;<br>]</pre><p>This means that <strong>Jest will change</strong> <strong>any file in the “node_modules”</strong> directory that <strong>does not start</strong> with <strong>“react-native”</strong> or <strong>“react-native-cookies”</strong>. You can add more exceptions by using the <strong>“|” </strong>sign. You can also use other codes to match different parts of the file name, such as the file type or the folder name.</p><h4><strong>🧩</strong> “transform”</h4><p>Jest will <strong>not actually change the original files</strong> in the “node_modules” directory. It will only <strong>change them temporarily in memory</strong> when it runs the tests. This is called <strong>“transformation”</strong> and it is done by using some tools called <strong>“transformers”</strong>. Jest has some built-in transformers that can handle common file types, such as JavaScript, TypeScript, JSON, etc. You can also use <strong>custom transformers</strong> that you install from npm or write yourself. You can specify which transformer to use for each file type by using the option <strong>“transform”</strong> in your <strong>Jest config</strong> file. For example:</p><pre>&quot;transform&quot;: {<br>  &quot;\\.[jt]sx?$&quot;: &quot;babel-jest&quot;,<br>  &quot;\\.ts$&quot;: &quot;ts-jest&quot;<br>}</pre><p>This means that <strong>Jest will use “babel-jest”</strong> to transform any file that <strong>ends with “.js”, “.jsx”, “.ts” or “.tsx”</strong>, and <strong>use “ts-jest” to transform any file that ends with “.ts”</strong>. You can use any regular expression to match the file type. You can also use different transformers for different files or directories by using an array of arrays.</p><h4><strong>🧩</strong> &quot;testEnvironment&quot;</h4><p>This option allows you to specify the test environment that will be used for testing. By default, Jest uses <strong><em>jsdom</em></strong>, which simulates a browser-like environment. However, for React Native projects, you may want to use <strong><em>node</em></strong> instead, which is <strong>faster</strong> and <strong>more lightweight</strong>. For example:</p><pre>&quot;testEnvironment&quot;: &quot;node&quot;</pre><p>This way, <strong>Jest</strong> will run your tests in a <strong>Node.js</strong> environment, which is more suitable for testing React Native components. You can also create your own custom test environment.</p><h4><strong>🧩</strong> &quot;testMatch&quot;</h4><p>The <strong><em>“testMatch”</em></strong> option is used to specify <strong>which files should be considered</strong> as <strong>test files by Jest</strong>. It is an array of glob patterns that match the file paths of your test files. For example, if you have a folder called <strong>“tests”</strong> in your project root, and you want to run all the files inside it that end with <strong>“.test.js”</strong> or <strong>“.spec.js”</strong>, you can use this option:</p><pre>&quot;testMatch&quot;: [<br>    &quot;&lt;rootDir&gt;/__tests__/*.js&quot;,<br>    &quot;&lt;rootDir&gt;/src/**/*.(test|spec).js&quot;<br>]</pre><p>The &lt;rootDir&gt; is a special token that Jest replaces with the path to the project root. The ** means any subdirectories, and the * means any file name. The (test|spec) means either <strong>“test”</strong> or <strong>“spec”</strong>, and the .js means the file extension. You can use other glob patterns to match different file names or extensions, such as .jsx, .ts, or .tsx.</p><p>You can also have <strong>multiple patterns in the array</strong>, and Jest will run any file that matches at least one of them. For example, if you have some test files in a folder called <strong>“tests”</strong> and some other test files in your <strong>“src”</strong> folder, you can use this option:</p><pre>&quot;testMatch&quot;: [&quot;&lt;rootDir&gt;/tests/**/*.(test|spec).js&quot;]</pre><p>This will run all the files in the “tests” folder or its subfolders that end with <strong>“.test.js”</strong> or <strong>“.spec.js”</strong>.</p><h4><strong>🧩</strong> &quot;coverageThreshold&quot;</h4><p>The <em>“coverageThreshold”</em> option is used to specify the <strong>minimum percentage of code coverage</strong> that your <strong>tests must achieve</strong>. Code coverage is a measure of how much of your code is executed by your tests. It can be calculated for different aspects of your code, such as <strong>statements</strong>, <strong>branches</strong>, <strong>functions</strong>, and <strong>lines</strong>.</p><p>The <strong>“coverageThreshold”</strong> option is an object that has a <strong>“global”</strong> property and optionally a <strong>“per-file”</strong> property. The “global” property is another object that has four properties: <strong>“statements”, “branches”, “functions”, and “lines”</strong>. Each of these properties is a number between 0 and 100 that represents the percentage of code coverage required for that aspect. For example, if you want to enforce that your tests cover at least <strong>80%</strong> of your statements, <strong>70%</strong> of your branches, <strong>90%</strong> of your functions, and <strong>85%</strong> of your lines, you can use this option:</p><pre>&quot;coverageThreshold&quot;: {<br>      &quot;global&quot;: {<br>        &quot;statements&quot;: 80,<br>        &quot;branches&quot;: 70,<br>        &quot;functions&quot;: 90,<br>        &quot;lines&quot;: 85<br>    }<br>}</pre><p>The <strong><em>“per-file”</em></strong> property is an array of objects that have a <strong><em>“path”</em></strong> property and a <strong><em>“threshold”</em></strong> property. The <strong>“path”</strong> property is a glob pattern that matches the file paths of your code files. The <strong>“threshold”</strong> property is an object that has the same four properties as the “global” object. This way, <strong>you can specify different coverage thresholds for different files</strong> or <strong>groups of files</strong>. For example, if you want to enforce that your tests cover at least <strong>95%</strong> of your <strong><em>components</em></strong> and <strong><em>hooks</em></strong>, and at least <strong>75%</strong> of everything else, you can use this option:</p><pre>&quot;coverageThreshold&quot;: {<br>      &quot;global&quot;: {<br>        &quot;statements&quot;: 75,<br>        &quot;branches&quot;: 75,<br>        &quot;functions&quot;: 75,<br>        &quot;lines&quot;: 75<br>      },<br>      &quot;per-file&quot;: [<br>        {<br>          &quot;path&quot;: &quot;**/src/components/*.tsx&quot;,<br>          &quot;threshold&quot;: {<br>            &quot;statements&quot;: 95,<br>            &quot;branches&quot;: 95,<br>            &quot;functions&quot;: 95,<br>            &quot;lines&quot;: 95<br>          }<br>        },<br>        {<br>          &quot;path&quot;: &quot;**/src/hooks/*.tsx&quot;,<br>          &quot;threshold&quot;: {<br>            &quot;statements&quot;: 95,<br>            &quot;branches&quot;: 95,<br>            &quot;functions&quot;: 95,<br>            &quot;lines&quot;: 95<br>          }<br>        }<br>    ]<br>}</pre><p>If you use the <strong><em>“coverageThreshold”</em></strong> option, <strong>Jest</strong> will fail the test run if the actual code coverage is lower than the specified thresholds. This can help you ensure that your tests are comprehensive and reliable.</p><blockquote>Let’s understand each <strong>Code Coverage</strong> terms <strong>“statements”</strong>, <strong>“branches”</strong>, <strong>“functions”</strong>, <strong>“lines”</strong> with examples below.</blockquote><p><strong>🍭 Statements<br></strong>A statement is a single instruction or command in your code, such as a variable declaration, an assignment, a function call, a loop, a conditional, etc. For example, in this code snippet:</p><pre>let x = 10; // statement 1<br>let y = 20; // statement 2<br>if (x &gt; y) { // statement 3<br>  console.log(&quot;x is greater&quot;); // statement 4<br>} else {<br>  console.log(&quot;y is greater&quot;); // statement 5<br>}</pre><p>There are five statements in total. The statement coverage is the percentage of statements that are executed by your tests. For example, if your tests only run the “else” branch of the conditional, then the <strong>statement coverage is 60%</strong> (3 out of 5 statements are executed).</p><p><strong>🍭 Branches<br></strong>A branch is a possible path of execution in your code, such as an “if” or “else” block, a “case” or “default” block in a switch statement, a ternary operator, etc. For example, in this code snippet:</p><pre>let x = 10; <br>let y = 20; <br>if (x &gt; y) { // branch 1<br>  console.log(&quot;x is greater&quot;); <br>} else { // branch 2<br>  console.log(&quot;y is greater&quot;); <br>}</pre><p>There are <strong>two branches</strong> in total. The branch coverage is the percentage of branches that are executed by your tests. For example, if your tests only run the “else” branch of the conditional, then the branch coverage is 50% (1 out of 2 branches are executed).</p><p><strong>🍭 Functions<br></strong>A function is a block of code that performs a specific task and can be invoked by other parts of your code. For example, in this code snippet:</p><pre>function add(a, b) { // function 1<br>  return a + b; <br>}<br><br>function subtract(a, b) { // function 2<br>  return a - b; <br>}<br><br>let x = add(10, 20); // statement 3<br>let y = subtract(30, 15); </pre><p>There are two functions in total. The function coverage is the percentage of functions that are invoked by your tests. For example, if your tests only call the “add” function, then the <strong>function coverage is 50%</strong> (1 out of 2 functions are invoked).</p><p><strong>🍭 Lines<br></strong>A line is a single line of code in your source file. For example, in this code snippet:</p><pre>let x = 10; // line 1<br>let y = 20; // line 2<br>if (x &gt; y) { // line 3<br>  console.log(&quot;x is greater&quot;); // line 4<br>} else {<br>  console.log(&quot;y is greater&quot;); // line 5<br>}</pre><p>There are five lines in total. The line coverage is the percentage of lines that are executed by your tests. For example, if your tests only run the “else” branch of the conditional, then the line <strong>coverage is 80%</strong> (4 out of 5 lines are executed).</p><h4>🧩 &quot;watchPlugins&quot;</h4><p>The watchPlugins option is a way to customize how Jest runs your tests in watch mode. Watch mode is a feature that lets you run only the tests that are related to the files you have changed in your code. This can save you time and make your testing process more efficient.</p><p>To use the watchPlugins option, you need to install a plugin that provides some extra functionality for your tests. For example, you can use <strong><em>jest-watch-typeahead</em></strong>, which is a plugin that lets you filter your tests by file name or test name. This can help you find and run the tests you want more easily.</p><p>To use <strong><em>jest-watch-typeahead</em></strong>, you need to do the following steps:</p><ul><li>Install jest-watch-typeahead as a dev dependency: <strong><em>yarn add --dev jest-watch-typeahead</em></strong></li><li>Add the plugin to your Jest config in package.json like below:</li></ul><pre>&quot;watchPlugins&quot;: [<br>    &quot;jest-watch-typeahead/filename&quot;,<br>    &quot;jest-watch-typeahead/testname&quot;<br>]</pre><p>This will enable you to use the jest-watch-typeahead plugin in your watch mode. When you run <strong><em>yarn test --watch</em></strong>, you will see two new options in the menu: <strong>p</strong> for filtering by file name and <strong>t</strong> for filtering by test name.</p><h3>Common Error in JEST config — ES6/Ts/cjs/mts</h3><p>You may encounter the error below while running tests on your screens.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*bTlYkAq595TaY2AX0te_Jg.png" /><figcaption>ES6 error with Jest runner</figcaption></figure><p>The reason for this error is that Jest failed to parse a file because it encountered an unexpected token. This can happen when your code or its dependencies use non-standard JavaScript syntax, or when Jest is not configured to support such syntax, such as ES6 syntax or TypeScript syntax.</p><p><strong><em>NOTE:</em></strong> To configure it properly and solve this issue, you need to keep in mind that both .babelrc and babel.config.js do the same thing. The file .babelrc was used in older configurations, but the file babel.config.js is being used by modern JS projects. So, use only babel.config.js to configure Babel properly.</p><h4><strong>SOLUTION</strong></h4><p>There are two ways to solve this error, but you need to maintain the sequence. If solution A does not work, then go for solution B.</p><p><strong>Solution (A):</strong> By <strong>“transform”</strong> option of Jest config.</p><p>I already explained in the previous section why we need to add a config option <strong>“transform”</strong> and what it does. Basically, an error like <strong>“Cannot use import statement outside a module”</strong> is usually caused by a file or its dependencies using <strong>non-standard JavaScript</strong> syntax.</p><p>To solve this issue, add a <strong>“transform”</strong> config to your Jest configuration file, either in the package.json or jest.config.js file, like below:</p><pre>// For jest.config.js<br>transform: {<br>    &#39;^.+\\.jsx?$&#39;: &#39;babel-jest&#39;<br>    &#39;^.+\\.tsx?$&#39;: &#39;&lt;rootDir&gt;/node_modules/ts-jest/preprocessor.js&#39;<br>}</pre><p>For React Native versions older than <strong>v0.61</strong>, you will have to use the code below instead of the code above.</p><pre>transform: {<br>    &#39;^.+\\.js$&#39;: &#39;&lt;rootDir&gt;/node_modules/react-native/jest/preprocessor.js&#39;<br>}</pre><p>Then add a babel.config.js file to the root of your project directory and add the code below.</p><pre>// babel.config.js<br>module.exports = {<br>  presets: [&#39;module:metro-react-native-babel-preset&#39;]<br>};</pre><p>If the above <strong>“preset” </strong>does not work for you, then add the code below.</p><pre>// babel.config.js<br>module.exports = {<br>  presets: [&#39;module:metro-react-native-babel-preset&#39;, &#39;@babel/preset-env&#39;]<br>};</pre><p><strong><em>NOTE: </em></strong>When you add the code, you must install the particular library via yarn/npm in your dev dependency using the command below (replace your library with the library name from the above code of configs that you need).</p><pre>yarn add --dev @babel/preset-env</pre><p><strong>Solution (B): </strong>Use the jest config option <strong>“transformIgnorePatterns”</strong>.</p><p><strong><em>Note:</em></strong> If the previous solution (A) does not work, then do not remove the Solution (A) codes of configs as they are necessary for the future.</p><p>So, why may solution (A) not have worked? This is because those files may not have been transformed into <strong>JavaScript</strong> syntax by the Jest preprocessor for any reason. However, you can <strong>ignore</strong> <strong>the transformation</strong> by the Jest preprocessor, as Jest can still read ES6 modules and TypeScript. Ignoring the transformation of those files will be a good solution.</p><p>Suppose you get an “import” error for <strong>“react-native-elements”</strong>. In that case, add the code below to your JEST configuration file.</p><pre>// jest.config.js<br>const config = {<br>  .....<br>  transformIgnorePatterns: [<br>    &#39;node_modules/(?!(jest-)?@react-native|react-native|react-native-elements/*)&#39;<br>  ],<br>  .....<br>}</pre><p>You can add more libraries like “react-native-elements” to the array by using the <strong>“|”</strong> symbol.</p><h3>Command to run test file</h3><p>Just use this below command to run your test file in terminal.</p><pre>yearn test test_file_name.test.js</pre><p>If you want to run all of your TEST file (File name ended with <strong><em>.test.js</em></strong>) then run this below command.</p><pre>yarn test</pre><p><strong><em>NOTE: </em></strong>Be sure “test” command was added in “scripts” section under package.json file in.</p><h3>React Native Testing Library (RNTL) APIs</h3><p>We will discuss now about all the essential APIs by React Native Testing Library.</p><h3>🪵 RNTL API — render()</h3><p>The render API is one of the methods that RNTL re-exports from <strong>DOM Testing Library</strong>. It allows you to render a React component into a container and returns an object that has a few properties, such as queries, container, baseElement, debug, re-render, unmount, asFragment, etc.</p><blockquote><strong>render()</strong> method deeply renders given <strong>React element</strong> and returns helpers <strong>to query the output components structure</strong>.</blockquote><p>Let’s see an example of how to use <strong>render()</strong> method. Below is my <strong><em>demo.screen.js</em></strong> Component on which I will apply test.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*rMQW09uiG6K_TVTmt-DKEw.png" /><figcaption><strong><em>demo.screen.js</em></strong> Component</figcaption></figure><p>Now let’s see how to use <strong>render()</strong> method in a Test for the above <strong><em>demo.screen.js</em></strong> Component. (Note: Please match <strong>red 🔴 </strong>&amp; <strong>green</strong> 🟢underlined in above <strong><em>demo.screen.js</em></strong> Component &amp; bellow test code).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1008/1*3JsLtrhD9RgQg-ARvCiPFQ.png" /><figcaption>Test written with <strong>render()</strong> API provided by RNTL</figcaption></figure><p>When we will run the command: <strong><em>yarn test Demo.test.js </em></strong>then we will see an output like below.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/850/1*mhw3_Nt2L7_WbK4KejqFow.png" /><figcaption>Test Passed ✅</figcaption></figure><p>🤚 Wait, we missed a <strong>STANDARD</strong> procedure while using <strong>render()</strong> API. The standard procedure is like below.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*gJAltPCY-Ihi4c05G2UbxQ.png" /><figcaption>Standard Procedure for <strong>render()</strong> API</figcaption></figure><p>So basically, latest <strong><em>render</em></strong> result is kept in <strong><em>screen</em></strong> variable that was imported from @testing-library/react-native package.</p><p>Using <strong><em>screen</em></strong> instead of destructuring <strong><em>render</em></strong> result is recommended approach. The benefit of using <strong><em>screen</em></strong> is you no longer need to keep the <strong><em>render</em></strong> call destructure up-to-date as you add/remove the queries you need. You only need to type <strong><em>screen</em></strong>. and let your editor&#39;s (VS Code for me) magic autocomplete take care of the rest.</p><h3>🐠 TEST Component with Provider — by render() API</h3><p>So, let’s say you want to test a component, but in that component, you used any Provider like <strong>Context Provider</strong>, <strong>Redux</strong> Provider, or any <strong>Theme Provider</strong>. So when you want to test that Component by test runner JEST, then <strong>will that component can get the value of Providers anyhow</strong>? The answer is No as you are not running any app; <strong>you are just running a Component which is a simple JS file</strong>. So then how can you still test that component <strong>without changing any simple line of code written for Providers</strong>?</p><p><strong>The solution is</strong> to create a custom <strong>render()</strong> API with the <strong>“wrapper”</strong> argument and then use that custom render() method instead of importing the <strong>render()</strong> API from <strong>RNTL</strong>.</p><blockquote><strong>Below an </strong>example <strong>with “wrapper” from “render()” API</strong></blockquote><p>At first, here is my <strong><em>“AuthContext”</em></strong> provider like below in <strong><em>“authContext.js”</em></strong> file.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/634/0*exiYWKChfsj2ErnB" /><figcaption><em>File: </em><strong><em>“authContext.js”</em></strong></figcaption></figure><p>Then a component <strong><em>“DemoScreen”</em></strong><em> which </em>looks like below in <strong><em>“demo.screen.js”</em></strong> file. I will apply TEST on this <strong><em>“DemoScreen”</em></strong> component. You see in this component I accessed value of <strong><em>“auth.username”</em></strong> from <strong>“AuthContext”</strong> provider.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*khCGQsV0ILvmlwLM" /><figcaption>File: <strong><em>“demo.screen.js”</em></strong></figcaption></figure><p>Now, below is how I implemented <strong>custom </strong><strong><em>render()</em></strong> by using <strong><em>“wrapper”</em></strong> argument in <strong><em>“test-utils.js”</em></strong> file. In this code, I wrapped the <strong>TESTING</strong> component <strong>{children}</strong> by <strong><em>&lt;AuthContext.Provider&gt;</em></strong>.</p><p><strong><em>Note:</em></strong> The <strong>TESTING</strong> component <strong>{children} </strong>means the component on which I’m going to apply TEST run. For me, it will be <strong><em>“DemoScreen” </em></strong>Component.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*KQwI1bAGJQHLctej" /><figcaption>File: <strong><em>“test-utils.js”</em></strong></figcaption></figure><p>Finally below is my TEST code that I wrote to test <strong><em>“DemoScreen” </em></strong>Component. In the code, you see I imported my custom <strong><em>“render”</em></strong> method instead of <strong><em>“render”</em></strong> method from <strong><em>“RNTL”. </em></strong>In the last line of code, I expected a text <strong><em>“Anis”</em></strong> in <strong><em>“DemoScreen”</em></strong> component. This text <strong><em>“Anis”</em></strong> came from <strong><em>“AuthContext”.</em></strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1018/0*qkUURj6uvy4GPQlw" /><figcaption>Final TEST file</figcaption></figure><p>Below I’m giving full code-block for <strong>“wrapper”</strong> argument of <strong>render()</strong> API to create a custom <strong>render()</strong> method.</p><pre>// ✅ File - &quot;authContext.js&quot;<br>// ✅ File - &quot;authContext.js&quot;<br><br>import { createContext } from &#39;react&#39;<br><br>const AuthContext = createContext(null)<br><br>export default AuthContext<br><br><br>// ✅ File - &quot;demo.screen.js&quot;<br>// ✅ File - &quot;demo.screen.js&quot;<br><br>import React, { useContext } from &#39;react&#39;<br>import { Text, ImageBackground } from &#39;react-native&#39;<br>import AuthContext from &#39;../util/context/authContext&#39;<br><br>export default function DemoScreen() {<br> const { auth, setAuth } = useContext(AuthContext)<br><br> return (<br>  &lt;ImageBackground source={require(&#39;../assets/homeBackdrop.png&#39;)}&gt;<br>   &lt;Text testID=&quot;greeting&quot;&gt;GREETING&lt;/Text&gt;<br>   &lt;Text testID=&quot;username&quot;&gt;{auth.username}&lt;/Text&gt;<br>  &lt;/ImageBackground&gt;<br> )<br>}<br><br><br>// ✅ File - &quot;test-utils.js&quot;<br>// ✅ File - &quot;test-utils.js&quot;<br><br>import React, { useState, useMemo } from &#39;react&#39;<br>import { render } from &#39;@testing-library/react-native&#39;<br>import AuthContext from &#39;../context/authContext&#39;<br><br>const AllTheProviders = ({ children }) =&gt; {<br> const [auth, setAuth] = useState({<br>  loggedIn: true,<br>  username: &#39;Anis&#39;<br> })<br><br> const authValue = useMemo(() =&gt; ({ auth, setAuth }), [auth, setAuth])<br><br> return (<br>  &lt;AuthContext.Provider value={authValue}&gt;{children}&lt;/AuthContext.Provider&gt;<br> )<br>}<br><br>const customRender = (component, options) =&gt;<br> render(component, { wrapper: AllTheProviders, ...options })<br><br>// re-export everything<br>export * from &#39;@testing-library/react-native&#39;<br><br>// override render method<br>export { customRender as render }<br><br><br>// ✅ File - &quot;Final TEST file&quot;<br>// ✅ File - &quot;Final TEST file&quot;<br><br>import React from &#39;react&#39;<br>import { render, screen } from &#39;../src/util/__test__/test-utils&#39;<br>import DemoScreen from &#39;../src/screens/demo.screen&#39;<br><br>describe(&#39;DemoScreen&#39;, () =&gt; {<br> it(&#39;should render the Demo Screen&#39;, () =&gt; {<br>  // Render the Demo Screen<br>  render(&lt;DemoScreen /&gt;)<br><br>  // Get the element with the testID &quot;greeting&quot;<br>  const userName = screen.getByTestId(&#39;username&#39;)<br><br>  // Expect the element to contain the text &quot;Anis&quot;<br>  expect(userName).toHaveTextContent(&#39;Anis&#39;)<br> })<br>})</pre><h3>🐠 “queries&quot; option — render() API</h3><p>The most important feature of render is providing a set of helpful queries that allow you to find certain elements in the view hierarchy.</p><p>Let’s see how many types of Query are there</p><ul><li>getBy... queries</li><li>getAllBy... queries</li><li>queryBy... queries</li><li>queryAllBy... queries</li><li>findBy... queries</li><li>findAllBy... queries</li></ul><p><strong><em>NOTE:</em></strong> getBy... query methods fail (throws error) when there is no matching element (null) but queryBy... methods don’t throw an error when no element (null) is found. We don’t want to get error from the line of fetching element. We want to get the error from the last line of TEST suit that is “expect”. So use queryBy... method instead of getBy.... Ex: queryBy... means queryByTestId.</p><p>Now let’s see the Query Predicates.</p><ul><li>...ByRole</li><li>...ByText</li><li>...ByPlaceholderText</li><li>...ByDisplayValue</li><li>...ByTestId</li><li>...ByLabelText</li><li>...ByHintText, ...ByA11yHint, ...ByAccessibilityHint</li></ul><h4>Query Types</h4><p>Now, let’s get the explanation of each query types.</p><p><strong>🪸 getBy. . . : </strong>getBy* queries return the first matching node for a query, and throw an error if no elements match or if more than one match is found.</p><p><strong>🪸 getAllBy. . . : </strong>getAllBy* queries return an array of all matching nodes for a query, and throw an error if no elements match.</p><p><strong>🪸 queryBy. . . </strong>: queryBy* queries return the first matching node for a query, and return null if no elements match. This is useful for asserting an element that is not present.</p><p><strong>🪸 queryAllBy. . . </strong>: queryAllBy* queries return an array of all matching nodes for a query, and return an empty array ([]) when no elements match.</p><p><strong>🪸 findBy. . .</strong> : findBy* queries return a promise which resolves when a matching element is found. The promise is rejected if no elements match or if more than one match is found after a default timeout of 1000 ms.</p><p><strong>🪸 findAllBy. . . : </strong>findAllBy* queries return a promise which resolves to an array of matching elements. The promise is rejected if no elements match after a default timeout of 1000 ms.</p><p><strong><em>NOTE:</em></strong> findBy* and findAllBy* queries accept optional waitForOptions object argument which can contain timeout, interval and onTimeout properties which have the same meaning as respective options for <a href="#d375"><strong><em>waitFor</em></strong></a> function.</p><h4>Query Predicates</h4><p>Now, let’s get the explanation of each query predicates.</p><p><strong>⛰️</strong> <strong>…ByRole: </strong>Supported methods are getByRole, getAllByRole, queryByRole, queryAllByRole, findByRole, findAllByRole</p><p>You need to set a role or accessibilityRole prop in your Component element like below.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*UzGz_x0hAR7g0ts4p63HmA.png" /><figcaption>Defined “role” in component to catch from TEST suit</figcaption></figure><p>Now the test suit is like below to access the button by role.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*5Z12y26J9YhM0d_6F7JoGw.png" /><figcaption>Access an element “button” by role</figcaption></figure><p><strong><em>NOTE:</em></strong> You need to set <strong><em>accessible</em></strong> prop to true in <strong><em>&lt;View&gt;</em></strong> host elements while using *ByRole as *ByRole needs to be considered an accessibility element.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*DWGr_VYv5LSKDKLLgIu3og.png" /><figcaption>TEST with getByRole in &lt;View&gt;</figcaption></figure><p>You can pass many other useful filters to methods like getByRole. Let’s see those filter options below. You can find details of each method by inspecting the method in VSCode.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*XuA2TEX1vdcDNrCHeH_VKg.png" /><figcaption>Filter options of getByRole Query</figcaption></figure><p><strong>⛰️ …ByText:</strong> Supported methods are getByText, getAllByText, queryByText, queryAllByText, findByText, findAllByText</p><p>This method will join &lt;Text&gt; siblings to find matches. This will allow for querying for strings that will be visually rendered together, but may be semantically separate React components.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/706/1*5EH_LTYhE39UlUzF2u1UeA.png" /><figcaption>Sibling Text Component</figcaption></figure><p><strong>⛰️ …ByPlaceholderText:</strong> Supported methods are getByPlaceholderText, getAllByPlaceholderText, queryByPlaceholderText, queryAllByPlaceholderText, findByPlaceholderText, findAllByPlaceholderText</p><p>Returns a <strong>Query Instance</strong> for a TextInput with a matching placeholder – may be a string or regular expression.</p><p><strong>⛰️ …ByDisplayValue:</strong> Supported methods are getByDisplayValue, getAllByDisplayValue, queryByDisplayValue, queryAllByDisplayValue, findByDisplayValue, findAllByDisplayValue</p><p>Returns a <strong>Query Instance </strong>for a TextInput with a matching display value – may be a string or regular expression. In below component I have a <strong>&lt;TextInput&gt;</strong> with initial value “Anis”.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*wasF6ecl8nLW8QCY4uX6VQ.png" /><figcaption>Component with a &lt;TextInput&gt; that has initial value “Anis”</figcaption></figure><p>Now apply TEST by getByDisplayValue to catch the &lt;TextInput&gt; by the initial display value “Anis”.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Pa_8ovRSYWlRCt2e5JKe8w.png" /><figcaption>TEST by initial Display value “Anis”</figcaption></figure><p><strong>⛰️ …ByTestId:</strong> Supported methods are getByTestId, getAllByTestId, queryByTestId, queryAllByTestId, findByTestId, findAllByTestId</p><p>Returns a <strong>Query Instance </strong>with matching <strong><em>testID</em></strong> prop like below. testID – may be a string or a regular expression.</p><pre>return (<br>  &lt;View testID=&quot;button&quot;&gt;<br>      &lt;Text&gt;Anis&lt;/Text&gt;<br>   &lt;/View&gt;<br> )</pre><p>And below is how the TEST suit should be written</p><pre>describe(&#39;Test using ByRole&#39;, () =&gt; {<br> it(&#39;should render the TEST Screen&#39;, async () =&gt; {<br>  // Render the Screen<br>  render(&lt;TestQuery_ByTestId /&gt;)<br><br>  // Get the BUTTON with the role/accessibilityRole as &quot;button&quot;<br>  const button = screen.getByTestId(&#39;button&#39;)<br><br>  // Expect the element to contain &quot;Anis&quot;<br>  expect(button).toHaveTextContent(&#39;Anis&#39;)<br> })<br>})</pre><p><strong><em>NOTE:</em></strong> It is recommended to use this only after the other queries don’t work for your use case. Using <strong>testID</strong> attributes do not resemble how your software is used and <strong>should be avoided if possible</strong>. However, they are particularly useful for end-to-end testing on real devices, e.g. using Detox and it&#39;s an encouraged technique to use there.</p><p><strong>⛰️ …ByLabelText:</strong> Supported methods are getByLabelText, getAllByLabelText, queryByLabelText, queryAllByLabelText, findByLabelText, findAllByLabelText</p><p>Returns a <strong>Query Instance </strong>with matching label:</p><ul><li>either by matching <strong><em>aria-label</em></strong>/<strong><em>accessibilityLabel</em></strong> prop</li><li>or by matching text content of view referenced by <strong><em>aria-labelledby</em></strong>/<strong><em>accessibilityLabelledBy</em></strong> prop</li></ul><p>Implementation code is as same as ⛰️ …ByDisplayValue.</p><h3>🐠 “update&quot; option — render() API</h3><p>During testing, you might want to simulate how your component behaves when its <strong>props change dynamically</strong>. For example, if your component receives new data from an API or user interactions trigger prop updates, you can use update() to test these scenarios.</p><p>When you call update(), you’re saying, “Hey, let’s change something about this component with some modifications!”</p><p>This update() simulates a React update at the root. If the new element has the <strong>same type</strong> and <strong>key</strong> as the previous element, the tree will be updated; otherwise, it will <strong>re-mount</strong> a new tree. This is useful when testing for <strong><em>componentDidUpdate</em></strong>(runs after a component updates) behavior, by passing updated props to the component.</p><p><strong>Tree Update vs. Re-Mount: </strong>If the <strong>type</strong> or <strong>key</strong> is <strong>different</strong>, RNTL don’t just update the existing tree. Instead, it <strong>creates a whole new tree</strong> (re-mount). Think of it like replacing a plant: sometimes you water the same plant (<strong>update</strong>), and other times you plant a new one (<strong>re-mount</strong>).</p><p>Let’s see an example. We have a component like below with a <strong>useEffect</strong> <strong>clean-up</strong> function to TEST the component <strong>Un-Mounting</strong> stuff.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*hEmDVJW6qbKYmZ3dQFVjOA.png" /><figcaption>Component to TEST render() &amp; update() mounting &amp; un-mounting</figcaption></figure><p>Now, I wrote a TEST suit below to test the above component.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*IKc-LIGTn3JR9aWHz9pucg.png" /><figcaption>TEST written by “RNTL” library</figcaption></figure><p>In the TEST suit, you may see that at first I used <strong>render()</strong>. Then I used <strong><em>update()</em></strong> two times. In the second <strong>update()</strong> I used a new key as <strong>“totallyNew”</strong>.</p><p>Now, when I ran the TEST file by JEST test runner with RNTL in environment, then I see below output in console.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*wH40zfzaNPEHoywb-4uIAg.png" /><figcaption>Output of TEST file</figcaption></figure><p>In the output we see, the <strong>clean-up</strong> function was called 2 times. The first one was called when I called the <strong>render()</strong> API. The second one called when I called the <strong>update()</strong> API for <strong>second time</strong> with new <strong>key “totallyNew”</strong>. So, in the <strong>first</strong> call of <strong>update() without key,</strong> din’t invoke the <strong>clean-up</strong> function.</p><p>So, it has been proved that <strong>update()</strong> with new value but <strong>without changing key</strong> will <strong>not MOUNT</strong> the component again &amp; it will just <strong>only update the existing DOM tree</strong>.</p><p>This test ensures that our component responds correctly to dynamic prop changes, and the update() option helps us to achieve that.</p><h3>🐠 “debug&quot; option — render() API</h3><p>Pretty prints deeply rendered component passed to render. Below is the code of debug.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*HvVaLPosEaR9yUjI2lkzeQ.png" /><figcaption>Implemented debug()</figcaption></figure><p>It logged the rendered component pretty deeply like below in the console.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*elmU0ymYg-3gAw291oBzyA.png" /><figcaption>Logged the <strong>rendered component</strong> in the console (Ignore my output font size as I fit it into a small space.)</figcaption></figure><h3>🪵 RNTL API — userEvent()</h3><p>There are 2 types of API in RNTL to handle all interactions like scrolling, press, etc. These are</p><ol><li>fireEvent() API</li><li>userEvent() API</li></ol><p><strong><em>FireEvent</em></strong> is the original event simulation API. It offers ability to invoke any event handler declared on either host or composite elements. If the element does not have onEventName event handler for passed eventName event, or the element is disabled, Fire Event will traverse up the component tree, looking for event handler on both host and composite elements along the way. By default it will not pass any event data, but the user might provide it in the last argument.</p><p>In contrast, <strong>UserEvent</strong> provides realistic event simulation for main user interactions like press or type from keyboard. Each of the interactions will trigger a sequence of events corresponding to React Native runtime behavior. These events will be invoked only on host elements, and will automatically receive event data corresponding to each event.</p><p>If <strong>UserEvent</strong> supports given interaction you should always prefer it over <strong><em>FireEvent</em></strong> counterpart, as it will make your tests much more realistic and hence reliable. In other cases, e.g. when event is not supported by User Event, or when invoking event handlers on <a href="#909a"><strong><em>composite elements</em></strong></a>, you have to use Fire Event as the only available option.</p><p><strong><em>fireEvent</em></strong> dispatches DOM events, whereas <strong>userEvent</strong> simulates full <em>interactions</em>, which may fire multiple events and do additional checks along the way.</p><h4>setup() option — userEvent()</h4><p>To use UserEvent(), at first you need to create an User Event object instance which can be used to trigger events. Before creating instance let’s understand some terms.</p><p><strong>Real Timer: </strong>Real Timer is the default timer used by JavaScript. It is based on the system clock and provides accurate timing information. However, it can cause issues when testing asynchronous code because it can take a long time to complete certain operations. To apply Real Timer just use this below code.</p><pre>// Setup UserEvent (with real timer)<br>  const user = userEvent.setup()</pre><p><strong>Fake Timer: </strong>Fake Timer is a timer that is not based on the system clock. Instead, it is controlled by the testing framework and can be advanced manually. This allows you to test asynchronous code more easily and quickly.</p><p><strong>Advanced Timer: </strong>An advanced timer is a tool that allows you to <em>fast-forward time</em> by 10 seconds, 5 seconds, 20 seconds, or any other specified duration. Unlike traditional timers, it doesn’t require you to wait for the entire duration before giving you an output. Instead, it provides you with an output within 100 milliseconds that will occur within the specified duration. To achieve this, the <strong>advanced timer takes the help of FakeTimer</strong>, which creates a fake timer inside the testing environment. This allows the advanced timer to perform its operation and give you a result from the future within just 100 milliseconds.</p><p>To apply <strong>Fake Timer</strong> with conjunction of <strong>Advance Timer</strong>, just use this below code instead of above code for Real Timers.</p><pre>// Activate FakeTimer<br>jest.useFakeTimers()<br><br>// Now, setup UserEvent (with Advance Timer)<br>const user = userEvent.setup({ <br>    delay: null,<br>    advanceTimers: (delay) =&gt; {<br>        jest.advanceTimersByTime(5000)<br>        // &quot;5000&quot; refers to advance the clock to 5s and show result now.<br>        // &quot;delay&quot; refers a basic &quot;130&quot; milliseconds to update a STATE.<br>    }<br>})</pre><p><strong><em>NOTE:</em></strong> If you don’t use <strong>advanceTimers()</strong> with <strong>UserEvent()</strong> like above then you will get an warning like below.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*7iK6_9s38uJhhLu8vcr1GA.png" /><figcaption>False positive warning (unnecessary warning) in console</figcaption></figure><p>Now, let’s see a complete example below. At first I’m giving you an example of component on which I will apply the UserEvent().</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*LBuhEsnJuIN-UikpVCtKxg.png" /><figcaption>Component to Test</figcaption></figure><p>Now, let’s see the TEST suit that I created using UserEvent() instance.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*oChurMRQQUXrDaPW2fViQA.png" /><figcaption>TEST suit to test userEvent() longPress method</figcaption></figure><p>Let me give you the TEST suit code in editor below.</p><pre><br>import React from &#39;react&#39;<br>import { render, screen, userEvent } from &#39;@testing-library/react-native&#39;<br>import UserEventTest from &#39;../src/screens/testScreens/userEventTest.screen&#39;<br><br>describe(&#39;Test using UserEvent&#39;, () =&gt; {<br> it(&#39;should render the TEST Screen&#39;, async () =&gt; {<br>  // Enable fakeTimers<br>  jest.useFakeTimers()<br><br>  // Setup UserEvent<br>  const user = userEvent.setup({<br>   delay: null,<br>   advanceTimers: (delay) =&gt; jest.advanceTimersByTime(10000)<br>  })<br><br>  // Render the Screen<br>  render(&lt;UserEventTest /&gt;)<br><br>  // Get the BUTTON with the testID &quot;button&quot;<br>  const button = screen.getByTestId(&#39;button&#39;)<br><br>  // Each time you will call a &quot;UserEvent&quot; method like below,<br>  // it will trigger this line &quot;jest.advanceTimersByTime(10000)&quot;<br>  await user.longPress(button)<br><br>  // Get the TEXT with the testID &quot;textConditional&quot;<br>  const textConditional = screen.queryByTestId(&#39;textConditional&#39;)<br><br>  // Expect the element to contain &quot;Text Visible&quot;<br>  expect(textConditional).toHaveTextContent(&#39;Text Visible&#39;)<br> })<br>})</pre><p>In the above example, you also got an idea with a real example of how to implement the <strong>UserEvent()</strong> API of RNTL for the longPress event. Like the longPress event, there are other events that UserEvent can support. These are listed below. Use them as like as I gave example above for longPress() method.</p><ul><li>press()</li><li>longPress()</li><li>type()</li><li>clear()</li><li>scrollTo()</li></ul><h3>🐠 Example of FireEvent() API</h3><p>Let me give you an example of <strong><em>fireEvent</em></strong> with fakeTimers and advanceTimersByTime(). fireEvent works exactly the same as userEvent in the case of fakeTimers and advanceTimersByTime(). However, fireEvent is a bit different from userEvent(). Below is the test suite that I wrote for the same component as above, with a press() and a setTimeout of 5000 ms in the action of the button press. Here is the test suite with fireEvent.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*oyfXaVP5y-415CGY-UeRtg.png" /><figcaption>TEST suit written for fireEvent()</figcaption></figure><p>Below is the code in editor for you.</p><pre>import React from &#39;react&#39;<br>import { <br>  render, <br>  screen, <br>  fireEvent, <br>  act } <br>from &#39;@testing-library/react-native&#39;<br>import FireEventTest from &#39;../src/screens/testScreens/fireEventTest.screen&#39;<br><br>describe(&#39;Test using UserEvent&#39;, () =&gt; {<br> it(&#39;should render the TEST Screen&#39;, async () =&gt; {<br>  // Enable fakeTimers<br>  jest.useFakeTimers()<br><br>  // Render the Screen<br>  render(&lt;FireEventTest /&gt;)<br><br>  // Get the BUTTON with the testID &quot;button&quot;<br>  const button = screen.getByTestId(&#39;button&#39;)<br><br>  // Fire an event &quot;Press&quot; by mouse<br>  fireEvent.press(button)<br><br>  // Apply a side-effect by act() function<br>  // We advanced the time 10s by this side-effect function<br>  act(() =&gt; {<br>   jest.advanceTimersByTime(10000)<br>  })<br><br>  // Get the TEXT with the testID &quot;textConditional&quot;<br>  const textConditional = screen.queryByTestId(&#39;textConditional&#39;)<br><br>  // Expect the element to contain &quot;Text Visible&quot;<br>  expect(textConditional).toHaveTextContent(&#39;Text Visible&#39;)<br><br>  jest.useRealTimers()<br> })<br>})</pre><p>If you place <strong><em>jest.advanceTimersByTime(10000)</em></strong> before <strong><em>fireEvent.press(button)</em></strong>, you will see an error because screen.queryByTestId and expect(textConditional) depend on a setTimeout state update with a delay of 5 seconds after the button press inside the component below.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*TPVFDVxLTK0K3j5LHErVvQ.png" /><figcaption>The component on which I applied fireEvent()</figcaption></figure><p>Like above, you can use fireEvent() for these actions too</p><ul><li>press()</li><li>changeText()</li><li>scroll() -&gt; ScrollView/ FlatList</li></ul><h3>🪵 RNTL API — waitFor()</h3><p>waitFor is a function provided by React Native Testing Library (RNTL) that waits for a condition to be true before continuing with the test. Here’s how it works:</p><ol><li>The waitFor function takes a callback function as an argument.</li><li>The callback function should return a truthy value when the condition is met.</li><li>If the callback function returns a falsy value, waitFor will wait and try again until the condition is met or the timeout is reached.</li></ol><p><strong><em>NOTE:</em></strong> Before React Native v0.71, there was no support for the waitFor() API. Before v0.71, waitFor was implemented using FakeTimer and continuous polling until a truthy value was returned.</p><p>Let’s implement the previous fireEvent() test suite using the waitFor() API this time.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*L37lakI4SbX_-VqL4yk5EA.png" /><figcaption>WaitFor() API implementation</figcaption></figure><p>Here, the timeout option specifies the maximum amount of time to wait for the condition to be true before timing out. The default value is 4500ms.</p><p>The interval option specifies the amount of time to wait between each check of the condition. The default value is 50ms.</p><p>The value <strong><em>10,000</em></strong> at the end of the above code refers to the maximum time this test will run, and every asynchronous (await) operation must be finished within this time. By default, this time is set to 5000 ms.</p><p>Again, the component is as same as before on which I applied the waitFor() test API. I’m providing the component again below.</p><figure><img alt="" src="https://cdn-images-1.medium.com/proxy/1*TPVFDVxLTK0K3j5LHErVvQ.png" /><figcaption>The component on which I applied WaitFor()</figcaption></figure><p>Below is the final code of WaitFor() in editor.</p><pre>import React from &#39;react&#39;<br>import { <br>    render, <br>    screen, <br>    fireEvent, <br>    waitFor <br>  } from &#39;@testing-library/react-native&#39;<br>import FireEventTest from &#39;../src/screens/testScreens/fireEventTest.screen&#39;<br><br>describe(&#39;Test using WaitFor&#39;, () =&gt; {<br> it(&#39;should render the TEST Screen&#39;, async () =&gt; {<br>  // Render the Screen<br>  render(&lt;FireEventTest /&gt;)<br><br>  // Get the BUTTON with the testID &quot;button&quot;<br>  const button = screen.getByTestId(&#39;button&#39;)<br><br>  // Fire an event &quot;Press&quot; by mouse<br>  fireEvent.press(button)<br><br>  await waitFor(<br>   () =&gt; {<br>    // Get the TEXT with the testID &quot;textConditional&quot;<br>    const textConditional = screen.queryByTestId(&#39;textConditional&#39;)<br><br>    // Expect the element to contain &quot;Text Visible&quot;<br>    expect(textConditional).toHaveTextContent(&#39;Text Visible&#39;)<br>   },<br>   { timeout: 6000, interval: 500 }<br>  )<br> }, 10000)<br>})</pre><p><strong><em>NOTE:</em></strong> If you are using any API (network call) inside <strong>“waitFor”</strong> operation then you may have encounter this below issue of “fetch”.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Hh1OtTDLNj0elN5a0d5Egg.png" /><figcaption>FETCH error for Jest</figcaption></figure><p><strong>SOLUTION:</strong> You have to install <strong><em>“cross-fetch”</em></strong> in your react native app by this below command.</p><pre>yarn add --dev cross-fetch</pre><p>Then just import the <strong>“cross-fetch”</strong> at the top of the file from where your TEST suit is fetching the Network Data by a Network Call. For my case it was Apollo GraphQL &amp; I just only imported the “cross-fetch” &amp; it worked.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*yFTzLc3DZKzcyMyKNJiWxw.png" /><figcaption>Imported “cross-fetch”</figcaption></figure><h3>What is Mocking ?</h3><p>Mocking is a technique used to replace real functions or modules with mock implementations during testing. This is useful when you want to isolate your tests from external dependencies or simulate certain scenarios that are difficult to reproduce in real-world conditions.</p><p>RNTL provides a set of utility functions that allow you to create mock functions and mock modules. You can use these functions to replace real functions or modules in your codebase and test how your code interacts with them.</p><h4>🍁 Difference between jest.fn() &amp; jest.mock()</h4><p><strong><em>jest.fn()</em></strong> is a function that returns a new, empty mock function. You can use this mock function to <strong>replace a real function</strong> in your codebase and test how it is called and what it returns. For example, you can use jest.fn() to create a mock function that simulates a network request and test how your code handles the response.</p><p><strong><em>jest.mock()</em></strong> is a function that allows you to <strong>replace a module</strong> with a mock implementation. This is useful when you want to test a module that has dependencies on other modules. You can use jest.mock() to replace the dependencies with mock implementations and test how your module interacts with them.</p><p>In summary, jest.fn() is used to create mock functions that replace real functions in your codebase, while jest.mock() is used to replace entire modules with mock implementations.</p><h4>🍁 How to Mock a Real Function (by jest.fn()) ?</h4><p><strong><em>jest.fn()</em></strong> is a function provided by the Jest testing framework that allows you to create mock functions that <strong>replace real functions</strong> in your codebase during testing. Below, I created a test suite where I created a mock function called <strong><em>‘mockFunction’</em></strong> using jest.fn().</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*xfxqahf21ptnI4Be4tdyNQ.png" /><figcaption>Created Mock function by jest.fn()</figcaption></figure><p>Look at the test suite where I created a mock function called <strong><em>‘mockFunction’</em></strong> using jest.fn() and passed it as a prop to the &lt;TestMock&gt; component. Finally, I checked whether the mock function <strong><em>‘mockFunction’</em></strong> was called or not in the last line of the test suite “expect(mockFunction).toHaveBeenCalled()”.</p><p>Below is the component where I applied the above test suite.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*gTKZezmXllG1BL8x6sFXYA.png" /><figcaption>Component on where I applied MOCK function<strong> “</strong><strong>mockFunction&quot;</strong></figcaption></figure><h4>🍁 How to Mock a Native Module (by jest.mock())?</h4><p>Some React Native components or third-party components rely on native code to be rendered. <strong>Native code</strong> is the code that runs on the device’s operating system, such as Android or iOS. For example, <strong>AsyncStorage</strong> is a native module that allows you to store and retrieve data from the device’s local storage. <strong>PermissionsAndroid</strong> is another native module that helps you request and check permissions for various features on Android devices.</p><p>However, when you run your tests with Jest, you don’t have access to the native code or the device’s environment. <strong>Jest</strong> runs your tests in a Node.js environment, which is different from the device’s environment. Therefore, you need to <strong>mock</strong> or fake the native modules that your components depend on.</p><p><strong>“Mocking means creating a simplified or simulated version of something that behaves in a similar way as the original thing</strong>.”</p><p>By mocking the native modules, you can avoid errors or unexpected behaviors when testing your components. You can also control how the <strong>native modules</strong> behave and return values in your tests. For example, you can <strong>mock AsyncStorage</strong> to return a specific value when you call AsyncStorage.getItem(key) in your test.</p><p>To mock a native module, you can use <strong><em>jest.mock(moduleName, factory)</em></strong> function. The <strong><em>moduleName</em></strong> is the name of the native module that you want to mock, such as ‘react-native’ or ‘@react-native-community/async-storage’. The <strong><em>factory</em></strong> is a function that returns an object with the methods and properties that you want to mock for the native module.</p><p>For example, if you want to mock AsyncStorage, you can write something like this in your setup file:</p><pre>jest.mock(&#39;@react-native-community/async-storage&#39;, () =&gt; ({<br>  getItem: jest.fn(() =&gt; Promise.resolve(&#39;some value&#39;)),<br>  setItem: jest.fn(() =&gt; Promise.resolve()),<br>}));</pre><p>This will create a mock version of AsyncStorage with two methods: <strong>getItem</strong> and <strong>setItem</strong>. The getItem method will always return a promise that resolves to ‘some value’, and the setItem method will always return a promise that resolves to nothing. You can use these methods in your tests as if they were the real AsyncStorage methods.</p><p>Similarly, if you want to <strong>mock PermissionsAndroid</strong>, you can write something like this in your setup file:</p><pre>jest.mock(&#39;react-native&#39;, () =&gt; ({<br>  ...jest.requireActual(&#39;react-native&#39;),<br>  PermissionsAndroid: {<br>    request: jest.fn(() =&gt; Promise.resolve(&#39;granted&#39;)),<br>    check: jest.fn(() =&gt; Promise.resolve(true)),<br>  },<br>}));</pre><p>This will create a mock version of PermissionsAndroid with two methods: <strong><em>request</em></strong> and <strong><em>check</em></strong>. The request method will always return a promise that resolves to ‘granted’, and the check method will always return a promise that resolves to true. You can use these methods in your tests as if they were the real PermissionsAndroid methods.</p><h4><strong><em>🍁 Another example of Native Module Mocking ( jest.mock() ) 👇</em></strong></h4><p>Let’s see another example of mocking a native module. Suppose you ran a test suite and rendered a component called <strong><em>MessageTab</em></strong>. Inside the MessageTab component, you used the react-native-orientation-locker native module. When you ran the test suite and called the MessageTab component, you got the error below.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*GCkq_hejnqu8v5zOaiX6gw.png" /><figcaption>ERROR due to not mocking Native Modules</figcaption></figure><p>The reason for the error is that you ran only a <strong>single JS file</strong> and not the entire app, and you did not run the app even in a device or simulator. Therefore, all <strong>native modules</strong> are out of scope to access. That’s why JEST can’t access the native orientation of device functions.</p><p>Here’s how I used the react-native-orientation-locker native module in my <strong><em>MessageTab</em></strong> component:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ElPJ2Mq25jxJ1ONKakDGHg.png" /><figcaption><strong>MessageTab</strong> Component with <strong>Native Module</strong> in use</figcaption></figure><p>So, I added mocking for react-native-orientation-locker inside my test suite before running the test, like the code below. This solved the error of invariant violation 🚀.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*jWF52--n9LB_izviLGOrrA.png" /><figcaption>TEST suit on which I applied jest.mock() on Native Module</figcaption></figure><h3>Some Advanced Share about RNTL</h3><p>React Native Testing Library allows you to write <strong>integration</strong> and <strong>component</strong> tests for your <strong>React Native</strong> app or library. While the JSX code used in tests closely resembles your React Native app, the things are <strong>not quite as simple</strong> as they might appear. Let’s understand some of them in this part.</p><h4>React renderers<a href="https://callstack.github.io/react-native-testing-library/docs/testing-env#react-renderers">​</a></h4><p>React allows you to write declarative code using <strong>JSX</strong>, write function or class components, or use hooks like useState. In order to output the results of your components <strong>it needs to work with a renderer</strong>. Every React app uses some type of renderer: <strong>React Native is a renderer for mobile apps</strong>, web apps use <strong>React DOM</strong>, and there are other more specialised renderers that can e.g. <strong>render to console</strong> or <strong>HTML canvas</strong>.</p><p>When you run your tests in React Native Testing Library, somewhat contrary to what the name suggest, they are actually not using React Native renderer. This is because this renderer needs to be run on iOS or Android operating system, so it would need to run on device or simulator.</p><h4>React Test Renderer<a href="https://callstack.github.io/react-native-testing-library/docs/testing-env#react-test-renderer">​</a></h4><p>Instead, <strong>RNTL </strong>uses<strong> </strong><strong>React Test Renderer</strong> which is a specialised renderer that <strong>allows rendering to pure JavaScript objects without access to mobile OS</strong>, and that can run in a Node.js environment using Jest (or any other JavaScript test runner).</p><p>Using React Test Renderer has pros and cons.</p><p>Benefits:</p><ul><li>Tests can run on most CIs (linux, etc) and do not require a mobile device or emulator</li><li>Faster test execution</li><li>Light runtime environment</li></ul><p>Disadvantages:</p><ul><li>Tests do not execute native code</li><li>Tests are not aware of view state that would be managed by native components, e.g. focus, unmanaged text boxes, etc.</li><li>Assertions do not operate on native view hierarchy</li><li>Runtime behaviours are simulated, sometimes imperfectly</li></ul><h4>Element tree<a href="https://callstack.github.io/react-native-testing-library/docs/testing-env#element-tree">​</a></h4><p>Invoking <strong><em>render()</em></strong> function results in creation of an <strong>element tree</strong>. This is done internally by invoking TestRenderer.create() method. The output <strong>tree represents your React Native component tree</strong>, each <strong>node</strong> of that tree is an <strong>“instance”</strong> of some <strong>React component.</strong></p><p><strong>To be more precise:</strong> Each <strong>node</strong> represents a <strong>React fiber</strong>, and <strong>only class components have instances</strong>, while function components store the hook state using <strong>fiber</strong>.</p><p><strong>Fiber:</strong> A <strong>fiber</strong> is a unit of work that <strong>represents a Component and its STATE</strong>. It is a lightweight thread-like structure that is used to manage the component tree and its updates. The <strong>fiber</strong> is created for each component and is responsible for scheduling the work and prioritizing the updates based on their importance.</p><h4>Fabric Renderer</h4><p>What is the <strong>DOM</strong> view in <strong>React</strong> is now the <strong>HOST</strong> view in <strong>React Native</strong>. So, below are two same:</p><p>React <strong>DOM</strong> view — &gt; React Native <strong>HOST</strong> view</p><p>Rendering to HOST views is made possible by the <strong>Fabric Renderer</strong>. Fabric lets React talk to each platform and manage its host view instances. The Fabric Renderer exists in JavaScript and targets interfaces made available by C++ code.</p><h4>HOST View Tree (and HOST View)<a href="https://reactnative.dev/architecture/glossary#host-view-tree-and-host-view">​</a></h4><p>Tree representation of views in the <strong>HOST</strong> platform (e.g. Android, iOS). On Android, the host <strong>views</strong> are instances of android.view.ViewGroup, android.widget.TextView, etc. which are the building blocks of the host <strong>view tree</strong>. The size and location of each <strong>HOST</strong> view are based on LayoutMetrics calculated with <strong>Yoga</strong>, and the style and content of each <strong>HOST</strong> view are based on information from the <strong>React Shadow Tree</strong>.</p><h4>HOST and Composite components</h4><p>One of the most important aspects of the element tree is that it is composed of both host and composite components:</p><ul><li><strong><em>HOST components: </em></strong><strong>HOST components</strong> are components that will have direct counterparts in the native view tree. Typical examples are &lt;View&gt;, &lt;Text&gt; , &lt;TextInput&gt;, and &lt;Image&gt; from React Native. You can think of these as analogue of &lt;div&gt;, &lt;span&gt; etc on the Web. You can also create your own host views as native modules or import them from 3rd party libraries, like <strong>React Navigation</strong> or <strong>React Native Gesture Handler</strong>.</li><li><strong><em>Composite components:</em></strong> <strong>Composite components</strong> are React code organisation units that exist only on the JavaScript side of your app. Typical examples are components you create (both function and class components), components imported from React Native (View, Text, etc) or from 3rd party packages.</li></ul><p>That might sound a bit confusing at first, since we put React Native’s <strong><em>View</em></strong> in both categories. There are actually two View components: composite one and host one. The relation between them is as follows:</p><ul><li>composite View is the type imported from react-native package. It’s a JavaScript component, which renders host View as its only child in the element tree.</li><li>host View , which you do not render directly. React Native takes the props you pass to the composite View, does some processing on them and <strong>passes them to host</strong> <strong><em>View</em></strong>.</li></ul><p>The part of the tree looks as follows:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/884/1*bqXMvmTSIRCEFIIYOUGbSA.png" /><figcaption>Composite &amp; HOST view</figcaption></figure><p>Similar relation exists between other composite and host pairs: e.g. Text , TextInput and Image components:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/788/1*_BOyABUqqKh7v1XVcIsRrw.png" /><figcaption>Composite &amp; HOST Text</figcaption></figure><p>Not all React Native components are organised this way, e.g. when you use Pressable (or TouchableOpacity) <strong>there is no HOST </strong><strong><em>Pressable</em></strong>, but composite Pressable is rendering a <strong><em>HOST </em></strong><strong><em>View</em></strong> with certain props being set:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/992/1*cuXag3B2ShdZqU1xTIMifQ.png" /><figcaption><strong>Composite</strong> Pressable with <strong>HOST</strong> view</figcaption></figure><p>You can get a simple definition of “COMPOSITE” &amp; “HOST” component in my tweeter post 👇</p><iframe src="https://cdn.embedly.com/widgets/media.html?type=text%2Fhtml&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;schema=twitter&amp;url=https%3A//twitter.com/anis_RNCore/status/1721225106507419725%3Fs%3D20&amp;image=https%3A//i.embed.ly/1/image%3Furl%3Dhttps%253A%252F%252Fabs.twimg.com%252Ferrors%252Flogo46x38.png%26key%3Da19fcc184b9711e1b4764040d3dc5c07" width="500" height="281" frameborder="0" scrolling="no"><a href="https://medium.com/media/09131ff36f202e67b9d45928c0b27c0a/href">https://medium.com/media/09131ff36f202e67b9d45928c0b27c0a/href</a></iframe><h4>Differentiating between host and composite elements</h4><p>An easy way to differentiate between <strong>host</strong> and <strong>composite</strong> elements is the <strong><em>type</em></strong> prop of given Component. Let’s have a look at below code.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*PM4WU_ErXAtJj3Mo" /><figcaption>Code for checking <strong>Component</strong> type (<strong>Composite</strong> or <strong>HOST</strong>)</figcaption></figure><p>In above code, the <strong>given Component </strong>is <strong><em>&lt;Pressable /&gt;</em></strong>. Inside function <strong><em>isHostElement(), </em></strong>I used element <strong>“type”</strong> property to check if the given Component <strong><em>&lt;Pressable /&gt;</em></strong> is a HOST component or a Composite component.</p><p>So, if <strong><em>typeof element.type</em></strong> return a <strong>“string”</strong> then given Component is a “<strong>HOST”</strong> component otherwise given Component is a <strong>“COMPOSITE”</strong> component.</p><p>For my case <strong><em>&lt;Pressable /&gt;</em> </strong>is a <strong>“COMPOSITE”</strong> component as it gave the below <strong>“Function type”</strong> instead of type <strong>“string”</strong>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*ayCD8CjGpP9OChet" /><figcaption><strong>Given Component</strong> type (Found that <strong>Given Component</strong> is a <strong>COMPOSITE component</strong>)</figcaption></figure><h4>Queries</h4><p>Most of the Testing Library queries return host components, in order to encourage best practices described above.</p><p>At this stage, there are some noteworthy exceptions:</p><ul><li>*ByText queries returns composite Text element</li><li>*ByDisplayValue queries returns composite TextInput element</li><li>*ByPlaceholderText queries returns composite TextInput element</li></ul><p>This will change in the near future, as RNTL team make efforts for all queries to return host components. Meanwhile it shouldn’t be a huge issue, as composite Text and TextInput generally pass their props down to <strong>HOST</strong> counterparts.</p><p>Additionally, UNSAFE_*ByType and UNSAFE_*ByProps queries can return both <strong>HOST</strong> and <strong>Composite</strong> components depending on used predicates. They are marked as unsafe precisely because testing composite components makes your test more fragile.</p><h3>🚀 Intro to E2E Testing</h3><p>If you have reached this far, then you are already an expert in <strong>Component Testing</strong> (JS testing) of React Native. Now, you need to dive into the top of the TESTING pyramid, which is E2E testing (End-to-End testing).</p><p>One of the most popular libraries for E2E testing for React Native apps is <strong>Detox</strong>. Detox is a <strong>gray box</strong> end-to-end testing and <strong>automation framework</strong> for mobile apps built with React Native. It supports both iOS and Android apps. <strong>Detox tests your mobile app while it’s running in a real device/simulator,</strong> interacting with it just like a real user.</p><p><strong><em>NOTE:</em></strong> I will be publishing an in-depth article on the Detox Testing Library very soon. The article will cover everything you need to know about Detox, including how to get started with it, its features, and how to use it to test your React Native apps.</p><p>Thank you for reading this article. I enjoy sharing my <strong>5 years</strong> of experience in <strong>JavaScript</strong>, <strong>React</strong>, <strong>React-native</strong> &amp; <strong>Node.js</strong> with you every day.</p><p>If you enjoyed reading this article, I would appreciate it if you could follow me on <a href="https://twitter.com/anis_RNCore"><strong><em>Twitter</em></strong></a> &amp; <a href="https://medium.com/@anisurrahmanbup"><strong><em>Medium</em></strong></a>. You can also leave your feedback and comments there. Thank you for your support and interest.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=219a5e7ea5dc" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>