{"id":7,"date":"2025-07-29T10:11:35","date_gmt":"2025-07-29T10:11:35","guid":{"rendered":"https:\/\/mithril.com.au\/wordpress\/?p=7"},"modified":"2025-07-29T10:11:35","modified_gmt":"2025-07-29T10:11:35","slug":"updating-react-native-my-journey","status":"publish","type":"post","link":"https:\/\/mithril.com.au\/wordpress\/index.php\/2025\/07\/29\/updating-react-native-my-journey\/","title":{"rendered":"Updating React Native (my journey)"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">Upgrading a React Native Project to a newer version<\/h2>\n\n\n\n<h4 class=\"wp-block-heading\">My Journey, in the hopes it will be useful to others.&nbsp;<\/h4>\n\n\n\n<p>So, it turns out that upgrading a react native project is a major task, not the least of which is there the error reporting is literally all over the place.<\/p>\n\n\n\n<p>I have a project currently running in 0.73 and I need to upgrade it to keep Google Playstore happy.<\/p>\n\n\n\n<p>(Min SDK needs to be 35 now).<\/p>\n\n\n\n<p>(Android, Windows environment)<\/p>\n\n\n\n<p>First off all, the upgrade tools have never worked for me. , not even when moving from one version of RN to the next one up.<\/p>\n\n\n\n<p>Also, I did&nbsp; not write the original version of the project, and I&#8217;m not convinced the original author actually understood RN very well.<\/p>\n\n\n\n<p>Patching the project in place never seems to work, so my approach for upgrades is:<\/p>\n\n\n\n<p>Start a new project with the latest RN version:<\/p>\n\n\n\n<p><a href=\"https:\/\/reactnative.dev\/docs\/getting-started-without-a-framework\"><code>https:\/\/reactnative.dev\/docs\/getting-started-without-a-framework<\/code><\/a><\/p>\n\n\n\n<p>(Note: Not using expo, it does not appear suitable for my requirements)<\/p>\n\n\n\n<p>Copy source code from existing project, including assets, but leave android folder alone for the time being.<\/p>\n\n\n\n<p><code>npx react-native run-android<\/code><\/p>\n\n\n\n<p>I took the opportunity to get all dependant packages to the latest version, by just iterating installing each package as it detected it was missing. Sometime iterating is as simple as hitting reload, sometimes you have to &#8220;run-android&#8221; again. (And sometimes you need to clear all the caches and restart).<\/p>\n\n\n\n<p>Here are some of the packages that needed special handling:<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">@nozbe\/watermelondb<\/h3>\n\n\n\n<p>This is an asynchronous wrapper around a native database, typically sqlite. It seems to work tolerably well once you take the time to properly .read the documentation. You do need to install a particular version of babel as watermelondb make extensive use of decorations.<\/p>\n\n\n\n<p>Getting this to run took a while, and the error in question was an unhelpful &#8220;n is not a function&#8221; message.<\/p>\n\n\n\n<p>After some trial and error, I found that the&nbsp;&nbsp;<strong>@action<\/strong>&nbsp; decoration was failing during the babel rendering phase. This is because it appears to be obsolete, and by replacing with&nbsp;<strong>@reader&nbsp;<\/strong>or&nbsp;<strong>@writer&nbsp;<\/strong>&nbsp;decorations it will now initialise properly. Remember to update your imports.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">@nozbe\/withobservables<\/h3>\n\n\n\n<p>This has moved. Do not install as a separate package as it is now included in\u00a0<strong>@nozbe\/watermelondb<\/strong>. Change your imports to:<\/p>\n\n\n\n<p><code>import { withObservables} from'@nozbe\/watermelondb\/react';<\/code><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">recompose<\/h3>\n\n\n\n<p>The project made considerable use of\u00a0<strong>recompose<\/strong>\u00a0which is no longer supported, and will crash on startup. The best fix is to not use it at all, but a quick workaround to stop it falling over is:to patch\u00a0<strong>node_modules\/recompose\/dist\/Recompose.cjs.js\u00a0<\/strong>and replace all references to\u00a0<strong>React.createFactory<\/strong>\u00a0with a call to:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>export function createFactory(type) {\n\n\u00a0 return React.createElement.bind(null, type);\n}\n<\/code><\/pre>\n\n\n\n<p>Clearly it is better to rewrite your code to not use recompose, but that is not always straightforward. (I eventually managed to remove all references to recompose.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>react-native-ui-lib<\/strong><\/h3>\n\n\n\n<p>Does not work with version 0.79, and throws an error like:&nbsp;<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>Attempt to invoke virtual method &#8216;void com.facebook.react.uimanager.UlManagerModule.onBatchComplete()&#8217; on a null object reference<\/p>\n<\/blockquote>\n\n\n\n<p>after the keyboard appears in a text input.<\/p>\n\n\n\n<p>Theoretically it can be patched but I just uninstalled the module and removed all references.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">debugging<\/h3>\n\n\n\n<p>0.79 has changed the debugger and the console output. Hitting &#8220;j&#8221; in the metro screen should open it, and as a debugger it seems much better at source code handling than prior versions. However, if your project is crashing the debugger can decide it doesn&#8217;t want to connect.<\/p>\n\n\n\n<p>The trick I found was to close the app on the device, restart, hit reload, and then hit the reconnect button in the debugger window before it has finished loading. That is usually sufficient to get the source maps loaded and to allow you to start putting in breakpoints<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">missing imports<\/h3>\n\n\n\n<p>RN is aggravatingly poor at letting you know that an import has failed to work. For instance:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p><code>import {jwt_decode} from 'jwt-decode';<\/code><\/p>\n<\/blockquote>\n\n\n\n<p>It turns out in the latest version of jwt-decode, the developer changed the import from&nbsp;<strong>jwt_decode&nbsp;<\/strong>to&nbsp;<strong>jwtDecode<\/strong>. There were no error messages, I just traced it to the point where I was attempting to call jwt_decode(token) and realised it wasn&#8217;t proceeding past there. So, double check imports, because RN is not very reliable. Sometimes it will tell you there is an issue, sometimes not.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">The many ways of restarting&nbsp;<\/h3>\n\n\n\n<h3 class=\"wp-block-heading\"><\/h3>\n\n\n\n<p>RN is, lets face it, a Frankenstienian monstrosity. It has a lot of moving parts and many different places you need to look to work out what is going wrong. During development, you need to frequently rebuild.<\/p>\n\n\n\n<p>Here are some of approaches, from simplest to most thorough:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Change your code and save changes<\/strong>: If your project is basically running, RN will pick up any changes and reapply.\u00a0<\/li>\n\n\n\n<li><strong>Hit Reload:\u00a0<\/strong>Hitting &#8220;r&#8221; on the metro server screen, or the reload button on the error screen on the device should reload any changes.<\/li>\n\n\n\n<li><strong>npx react-native\u00a0run-android:<\/strong>\u00a0should rebuild everything, including the underlying android SDK java components. Generally a good idea if you install or uninstall modules, but you can get away with just a reload IF the module is pure javascript\/typescript. It&#8217;s not always easy to tell.<\/li>\n\n\n\n<li><strong>npx react-native start &#8211;reset-cache:\u00a0<\/strong>Do this after the run-android step if something is not working when you think it should be.\u00a0<\/li>\n\n\n\n<li><strong>clear caches and reinstall modules:\u00a0<\/strong>See\u00a0<strong>cleanall.bat<\/strong>\u00a0below.<\/li>\n<\/ol>\n\n\n\n<pre class=\"wp-block-code\"><code>@echo off\necho Deleting metro cache\nrd %localappdata%\\Temp\\metro-cache \/s \/q \ndel %localappdata%\\Temp\\haste-map*\necho Cleaning build\ncd android\ncall gradlew clean \ncd .. \necho Deleting node_modules\nrd node_modules \/q \/s \necho Cleaning npm cache\ncall npm cache clean --force \necho Installing modules\ncall npm install --legacy-peer-deps\necho Done<\/code><\/pre>\n\n\n\n<p><\/p>\n\n\n\n<p>This will clear all the caches and reinstall the modules. This will sometimes sort out strange behaviours.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Reconnecting<\/h3>\n\n\n\n<p>Sometimes the device loses track of where the metro server is, and vice-versa.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p><code>adb reverse tcp:8081 tcp:8081<\/code><\/p>\n<\/blockquote>\n\n\n\n<p>should map the ports appropriately. Look up adb parameters to manage more than one device.<\/p>\n\n\n\n<p>Once this is done, close and restart the app on the device for a clean reconnect.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Patching<\/h3>\n\n\n\n<p>npm modules get out of date with the current version of RN and need to be tweaked or modified to get your project to run.<\/p>\n\n\n\n<p>Fortunately, there is a way of tweaking a module in your own project without having to go for a full scale fork in git.<\/p>\n\n\n\n<p><a href=\"https:\/\/www.blogger.com\/blog\/post\/edit\/393750603125777365\/3999060949434481377#\">patch-package<\/a>&nbsp;https:\/\/www.npmjs.com\/package\/patch-package creates a patch file from your changes and reapplies the change when you do a fresh install.<\/p>\n\n\n\n<p><em>Note: It&nbsp; does require&nbsp;<strong>git<\/strong>&nbsp;to be available from the command line to run properly<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Upgrading a React Native Project to a newer version My Journey, in the hopes it will be useful to others.&nbsp; So, it turns out that upgrading a react native project is a major task, not the least of which is there the error reporting is literally all over the place. I have a project currently [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-7","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/mithril.com.au\/wordpress\/index.php\/wp-json\/wp\/v2\/posts\/7","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mithril.com.au\/wordpress\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mithril.com.au\/wordpress\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mithril.com.au\/wordpress\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mithril.com.au\/wordpress\/index.php\/wp-json\/wp\/v2\/comments?post=7"}],"version-history":[{"count":1,"href":"https:\/\/mithril.com.au\/wordpress\/index.php\/wp-json\/wp\/v2\/posts\/7\/revisions"}],"predecessor-version":[{"id":8,"href":"https:\/\/mithril.com.au\/wordpress\/index.php\/wp-json\/wp\/v2\/posts\/7\/revisions\/8"}],"wp:attachment":[{"href":"https:\/\/mithril.com.au\/wordpress\/index.php\/wp-json\/wp\/v2\/media?parent=7"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mithril.com.au\/wordpress\/index.php\/wp-json\/wp\/v2\/categories?post=7"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mithril.com.au\/wordpress\/index.php\/wp-json\/wp\/v2\/tags?post=7"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}