{"componentChunkName":"component---src-templates-markdown-template-jsx","path":"/developers/client-sdks/react-native/upgrade-to-version-4/","result":{"data":{"pageMetadata":{"title":"Upgrade to Version 4","path":"/developers/client-sdks/react-native/upgrade-to-version-4/","hideFromNav":null,"sourceCode":null,"metadataParent":{"title":"React Native","path":"/developers/client-sdks/react-native/","sourceCode":"https://github.com/mParticle/react-native-mparticle","hasVersionPicker":null,"metadataChildren":[{"title":"Getting Started","path":"/developers/client-sdks/react-native/getting-started/","order":1,"label":null},{"title":"Identity","path":"/developers/client-sdks/react-native/identity/","order":2,"label":null},{"title":"Upgrade to Version 4","path":"/developers/client-sdks/react-native/upgrade-to-version-4/","order":3,"label":null}],"metadataParent":{"title":"Client SDKs","path":"/developers/client-sdks/","metadataChildren":[{"title":"Alexa","path":"/developers/client-sdks/alexa/","order":1,"label":null},{"title":".NET MAUI","path":"/developers/client-sdks/maui/","order":null,"label":null},{"title":"AMP","path":"/developers/client-sdks/amp/","order":null,"label":null},{"title":"Android","path":"/developers/client-sdks/android/","order":null,"label":null},{"title":"Cordova","path":"/developers/client-sdks/cordova/","order":null,"label":null},{"title":"Direct Url Routing","path":"/developers/client-sdks/direct-url-routing/","order":null,"label":null},{"title":"Flutter","path":"/developers/client-sdks/flutter/","order":null,"label":null},{"title":"iOS","path":"/developers/client-sdks/ios/","order":null,"label":null},{"title":"React Native","path":"/developers/client-sdks/react-native/","order":null,"label":null},{"title":"Roku","path":"/developers/client-sdks/roku/","order":null,"label":null},{"title":"Unity","path":"/developers/client-sdks/unity/","order":null,"label":null},{"title":"Web","path":"/developers/client-sdks/web/","order":null,"label":null},{"title":"Xbox","path":"/developers/client-sdks/uwp/","order":null,"label":null}],"metadataParent":{"title":"Developers","path":"/developers/","metadataChildren":[{"title":"API Credential Management","path":"/developers/credential-management/","order":null,"label":null},{"title":"API References","path":"/developers/apis/","order":null,"label":null},{"title":"Client SDKs","path":"/developers/client-sdks/","order":null,"label":null},{"title":"Guides","path":"/developers/guides/","order":null,"label":null},{"title":"Media SDKs","path":"/developers/media-sdks/","order":null,"label":null},{"title":"Quickstart","path":"/developers/quickstart/","order":null,"label":null},{"title":"Server SDKs","path":"/developers/server-sdks/","order":null,"label":null},{"title":"The Developer's Guided Journey to mParticle","path":"/developers/developersjourney/","order":null,"label":null},{"title":"Tools","path":"/developers/tools/","order":null,"label":null}],"metadataParent":null}}}},"markdownRemark":{"html":"<p>Version 4 of <code class=\"language-text\">react-native-mparticle</code> introduces two breaking changes: the native iOS mParticle SDK and kits come from Swift Package Manager (SPM) by default, and <code class=\"language-text\">MParticle.Rokt.selectPlacements</code> accepts only an array of placeholder names for embedded placements.</p>\n<p>This guide covers upgrades from 3.x. For a new integration, follow <a href=\"/developers/client-sdks/react-native/getting-started/\">Getting Started</a>. If you are upgrading from 2.x or earlier, also follow <a href=\"https://github.com/mParticle/react-native-mparticle/blob/main/MIGRATING.md#migrating-from-versions--300\">Migrating from versions below 3.0.0</a> for the underlying native SDK changes.</p>\n<p>Update the wrapper package, then follow the platform steps below before building:</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre style=\"counter-reset: linenumber NaN\" class=\"language-bash line-numbers\"><code class=\"language-bash\"><span class=\"token function\">npm</span> <span class=\"token function\">install</span> react-native-mparticle@^4.0.0</code><span aria-hidden=\"true\" class=\"line-numbers-rows\" style=\"white-space: normal; width: auto; left: 0;\"><span></span></span></pre></div>\n<p>With Expo, use <code class=\"language-text\">npx expo install react-native-mparticle@^4.0.0</code> instead.</p>\n<h2 id=\"ios-dependencies\" style=\"position:relative;\"><a href=\"#ios-dependencies\" aria-label=\"ios dependencies permalink\" class=\"anchor before\"><svg width=\"16px\" height=\"17px\" viewBox=\"0 0 16 17\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n                <g id=\"Symbols\" stroke=\"none\" stroke-width=\"1\" fill=\"none\" fill-rule=\"evenodd\">\n                    <g id=\"Icon/Link\" fill=\"#98A0A3\" fill-rule=\"nonzero\">\n                        <g id=\"link\">\n                            <path d=\"M9.5,12.4 C9.6,12.4 9.7,12.4 9.9,12.4 C9.8,12.5 9.8,12.5 9.7,12.6 L7.5,14.8 C5.8,16.5 3,16.5 1.3,14.8 C-0.4,13.1 -0.4,10.3 1.3,8.6 L3.5,6.4 C3.6,6.3 3.6,6.3 3.7,6.2 C5,5 6.9,4.8 8.4,5.5 C8.8,5.7 9.3,6 9.6,6.4 C10,6.7 10.2,7.2 10.5,7.6 C10.2,7.9 9.9,8 9.5,8 C9.4,8 9.2,8 9.1,7.9 C8.9,7.5 8.5,7.2 8.1,6.9 C7,6.2 5.5,6.4 4.5,7.3 L3.8,8 L2.3,9.5 C1.2,10.6 1.2,12.5 2.3,13.6 C3.4,14.7 5.3,14.7 6.4,13.6 L7.9,12.1 C8.4,12.3 8.9,12.4 9.5,12.4 Z M14.7,1.3 C13,-0.4 10.2,-0.4 8.5,1.3 L6.3,3.5 C6.2,3.6 6.2,3.6 6.1,3.7 C6.7,3.7 7.4,3.7 8,3.9 L9.5,2.4 C10.6,1.3 12.5,1.3 13.6,2.4 C14.7,3.5 14.7,5.4 13.6,6.5 L12.1,8 L11.4,8.7 C10.4,9.7 8.9,9.8 7.8,9.1 C7.4,8.9 7.1,8.5 6.8,8.1 C6.7,8.1 6.5,8 6.4,8 C6,8 5.6,8.2 5.4,8.4 C5.6,8.8 5.9,9.3 6.3,9.6 C6.6,10 7.1,10.2 7.5,10.5 C9,11.2 10.9,11 12.3,9.8 C12.4,9.7 12.4,9.7 12.5,9.6 L14.7,7.4 C16.4,5.7 16.4,3 14.7,1.3 Z\" id=\"Shape\"></path>\n                        </g>\n                    </g>\n                </g>\n            </svg></a>iOS dependencies</h2>\n<p>React Native and the wrapper still install through CocoaPods. Running <code class=\"language-text\">pod install</code> now links the mParticle core SDK and configured kits into your app target as Swift packages pinned to exact versions. The default Apple SDK version is selected and tested for your installed wrapper release. Kits without an explicit version use the core SDK version.</p>\n<p>An app without kits or manually declared native SDK dependencies needs no dependency configuration change. For apps with kit pods or manually linked packages:</p>\n<ol>\n<li>Remove every explicit mParticle and Rokt pod declaration from <code class=\"language-text\">ios/Podfile</code>, including <code class=\"language-text\">mParticle-Apple-SDK</code>, its split ObjC/Swift pods, <code class=\"language-text\">mParticle-Rokt</code>, <code class=\"language-text\">Rokt-Widget</code>, <code class=\"language-text\">RoktSDKPlus</code>, and any directly declared <code class=\"language-text\">RoktContracts</code>, <code class=\"language-text\">RoktUXHelper</code>, <code class=\"language-text\">DcuiSchema</code>, or <code class=\"language-text\">RoktPaymentExtension</code> pods.</li>\n<li>Remove those names from any <code class=\"language-text\">pre_install</code> hook that builds them as dynamic frameworks. Delete the hook if it has no other entries; keep configuration needed by other dependencies.</li>\n<li>Remove mParticle or Rokt Swift packages you added by hand from your app target’s <strong>Frameworks, Libraries, and Embedded Content</strong> and the project’s <strong>Package Dependencies</strong> in Xcode. Installation adds the configured packages back.</li>\n<li>\n<p>Set <code class=\"language-text\">platform :ios, &#39;15.6&#39;</code> or later, and list your kits before the first <code class=\"language-text\">target</code> block. For standard Rokt placements:</p>\n<div class=\"gatsby-highlight\" data-language=\"ruby\"><pre style=\"counter-reset: linenumber NaN\" class=\"language-ruby line-numbers\"><code class=\"language-ruby\">platform <span class=\"token symbol\">:ios</span><span class=\"token punctuation\">,</span> <span class=\"token string\">'15.6'</span>\n<span class=\"token variable\">$RNMParticleSPMKits</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">[</span><span class=\"token string\">'mParticle-Rokt'</span><span class=\"token punctuation\">]</span></code><span aria-hidden=\"true\" class=\"line-numbers-rows\" style=\"white-space: normal; width: auto; left: 0;\"><span></span><span></span></span></pre></div>\n<p>For iOS Shoppable Ads, use <code class=\"language-text\">[&#39;RoktSDKPlus&#39;]</code> instead. It includes <code class=\"language-text\">mParticle-Rokt</code> and <code class=\"language-text\">RoktPaymentExtension</code>; do not list both kits. For other kits and optional exact version overrides, see <a href=\"/developers/client-sdks/react-native/getting-started/#swift-package-manager-default\">SPM configuration</a>.</p>\n</li>\n<li>Run <code class=\"language-text\">bundle exec pod install</code> from <code class=\"language-text\">ios/</code>. If a pod would install a second copy of the SDK, installation stops and lists the pods to remove.</li>\n<li>Resolve packages in Xcode, build and launch a Debug build to check for duplicate-SDK errors, and commit the <code class=\"language-text\">.xcodeproj</code> change and <code class=\"language-text\">ios/&lt;App&gt;.xcworkspace/xcshareddata/swiftpm/Package.resolved</code>.</li>\n</ol>\n<p>The default static-library setup and both <code class=\"language-text\">use_frameworks!</code> linkages are supported without a mParticle <code class=\"language-text\">pre_install</code> hook. Swift initialization continues using <code class=\"language-text\">import mParticle_Apple_SDK</code>.</p>\n<p>On each <code class=\"language-text\">pod install</code>, kits from the maintained catalog that are absent from <code class=\"language-text\">$RNMParticleSPMKits</code> are unlinked. Remove packages from custom URLs manually in Xcode when you stop using them.</p>\n<h3 id=\"expo\" style=\"position:relative;\"><a href=\"#expo\" aria-label=\"expo permalink\" class=\"anchor before\"><svg width=\"16px\" height=\"17px\" viewBox=\"0 0 16 17\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n                <g id=\"Symbols\" stroke=\"none\" stroke-width=\"1\" fill=\"none\" fill-rule=\"evenodd\">\n                    <g id=\"Icon/Link\" fill=\"#98A0A3\" fill-rule=\"nonzero\">\n                        <g id=\"link\">\n                            <path d=\"M9.5,12.4 C9.6,12.4 9.7,12.4 9.9,12.4 C9.8,12.5 9.8,12.5 9.7,12.6 L7.5,14.8 C5.8,16.5 3,16.5 1.3,14.8 C-0.4,13.1 -0.4,10.3 1.3,8.6 L3.5,6.4 C3.6,6.3 3.6,6.3 3.7,6.2 C5,5 6.9,4.8 8.4,5.5 C8.8,5.7 9.3,6 9.6,6.4 C10,6.7 10.2,7.2 10.5,7.6 C10.2,7.9 9.9,8 9.5,8 C9.4,8 9.2,8 9.1,7.9 C8.9,7.5 8.5,7.2 8.1,6.9 C7,6.2 5.5,6.4 4.5,7.3 L3.8,8 L2.3,9.5 C1.2,10.6 1.2,12.5 2.3,13.6 C3.4,14.7 5.3,14.7 6.4,13.6 L7.9,12.1 C8.4,12.3 8.9,12.4 9.5,12.4 Z M14.7,1.3 C13,-0.4 10.2,-0.4 8.5,1.3 L6.3,3.5 C6.2,3.6 6.2,3.6 6.1,3.7 C6.7,3.7 7.4,3.7 8,3.9 L9.5,2.4 C10.6,1.3 12.5,1.3 13.6,2.4 C14.7,3.5 14.7,5.4 13.6,6.5 L12.1,8 L11.4,8.7 C10.4,9.7 8.9,9.8 7.8,9.1 C7.4,8.9 7.1,8.5 6.8,8.1 C6.7,8.1 6.5,8 6.4,8 C6,8 5.6,8.2 5.4,8.4 C5.6,8.8 5.9,9.3 6.3,9.6 C6.6,10 7.1,10.2 7.5,10.5 C9,11.2 10.9,11 12.3,9.8 C12.4,9.7 12.4,9.7 12.5,9.6 L14.7,7.4 C16.4,5.7 16.4,3 14.7,1.3 Z\" id=\"Shape\"></path>\n                        </g>\n                    </g>\n                </g>\n            </svg></a>Expo</h3>\n<p>Keep your <code class=\"language-text\">iosKits</code> configuration: the plugin maps recognized names to Swift packages by default. Use <code class=\"language-text\">iosSpmKits</code> for kits outside the <a href=\"https://github.com/mParticle/react-native-mparticle/blob/main/ios/mparticle_spm_kits.json\">maintained catalog</a>.</p>\n<p>Set the iOS deployment target to <strong>15.6</strong> or later through <code class=\"language-text\">expo-build-properties</code>; the mParticle plugin does not set it. Clean prebuilds regenerate the native project and its package lockfile, but the same wrapper release and configuration select the same exact core SDK version. Set <code class=\"language-text\">iosSdkVersion</code> only for an intentional override. Kits without an explicit version use the core version. See the <a href=\"/developers/client-sdks/react-native/getting-started/#expo\">Expo setup</a> for the configuration example.</p>\n<p>Run <code class=\"language-text\">npx expo prebuild --clean</code>, then <code class=\"language-text\">npx expo run:ios</code>. Also run a clean prebuild whenever you switch <code class=\"language-text\">iosDependencyManager</code> between <code class=\"language-text\">&quot;spm&quot;</code> and <code class=\"language-text\">&quot;cocoapods&quot;</code>.</p>\n<p>For Shoppable Ads, use <code class=\"language-text\">&quot;iosKits&quot;: [&quot;RoktSDKPlus&quot;]</code>. After prebuild, add native payment-extension registration following the <a href=\"/developers/client-sdks/react-native/getting-started/#rokt-setup\">Rokt setup instructions</a>, and reapply it after regenerating native projects.</p>\n<h3 id=\"cocoapods-fallback-and-tvos\" style=\"position:relative;\"><a href=\"#cocoapods-fallback-and-tvos\" aria-label=\"cocoapods fallback and tvos permalink\" class=\"anchor before\"><svg width=\"16px\" height=\"17px\" viewBox=\"0 0 16 17\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n                <g id=\"Symbols\" stroke=\"none\" stroke-width=\"1\" fill=\"none\" fill-rule=\"evenodd\">\n                    <g id=\"Icon/Link\" fill=\"#98A0A3\" fill-rule=\"nonzero\">\n                        <g id=\"link\">\n                            <path d=\"M9.5,12.4 C9.6,12.4 9.7,12.4 9.9,12.4 C9.8,12.5 9.8,12.5 9.7,12.6 L7.5,14.8 C5.8,16.5 3,16.5 1.3,14.8 C-0.4,13.1 -0.4,10.3 1.3,8.6 L3.5,6.4 C3.6,6.3 3.6,6.3 3.7,6.2 C5,5 6.9,4.8 8.4,5.5 C8.8,5.7 9.3,6 9.6,6.4 C10,6.7 10.2,7.2 10.5,7.6 C10.2,7.9 9.9,8 9.5,8 C9.4,8 9.2,8 9.1,7.9 C8.9,7.5 8.5,7.2 8.1,6.9 C7,6.2 5.5,6.4 4.5,7.3 L3.8,8 L2.3,9.5 C1.2,10.6 1.2,12.5 2.3,13.6 C3.4,14.7 5.3,14.7 6.4,13.6 L7.9,12.1 C8.4,12.3 8.9,12.4 9.5,12.4 Z M14.7,1.3 C13,-0.4 10.2,-0.4 8.5,1.3 L6.3,3.5 C6.2,3.6 6.2,3.6 6.1,3.7 C6.7,3.7 7.4,3.7 8,3.9 L9.5,2.4 C10.6,1.3 12.5,1.3 13.6,2.4 C14.7,3.5 14.7,5.4 13.6,6.5 L12.1,8 L11.4,8.7 C10.4,9.7 8.9,9.8 7.8,9.1 C7.4,8.9 7.1,8.5 6.8,8.1 C6.7,8.1 6.5,8 6.4,8 C6,8 5.6,8.2 5.4,8.4 C5.6,8.8 5.9,9.3 6.3,9.6 C6.6,10 7.1,10.2 7.5,10.5 C9,11.2 10.9,11 12.3,9.8 C12.4,9.7 12.4,9.7 12.5,9.6 L14.7,7.4 C16.4,5.7 16.4,3 14.7,1.3 Z\" id=\"Shape\"></path>\n                        </g>\n                    </g>\n                </g>\n            </svg></a>CocoaPods fallback and tvOS</h3>\n<p>To retain native CocoaPods dependencies temporarily, set <code class=\"language-text\">$RNMParticleDisableSPM = true</code> before the first Podfile <code class=\"language-text\">target</code> block and retain your kit pods. In Expo, set <code class=\"language-text\">&quot;iosDependencyManager&quot;: &quot;cocoapods&quot;</code>.</p>\n<p>If any tvOS target in the Podfile uses this wrapper, the whole Podfile must use this fallback. The minimum tvOS deployment target is <strong>15.6</strong>. The default SPM integration supports iOS only.</p>\n<p>Remove leftover mParticle/Rokt Swift packages in Xcode when switching to CocoaPods. Keep the required framework-linking configuration and, for Swift apps without kits, the umbrella-pod declaration described in <a href=\"/developers/client-sdks/react-native/getting-started/#cocoapods-deprecated\">CocoaPods setup</a>.</p>\n<p>This fallback is deprecated. CocoaPods trunk is <a href=\"https://blog.cocoapods.org/CocoaPods-Specs-Repo/\">scheduled to stop accepting new pods and versions on December 2, 2026</a>; existing published versions remain available. SPM-only kits such as <code class=\"language-text\">RoktSDKPlus</code> cannot use the fallback.</p>\n<h2 id=\"rokt-embedded-placeholders\" style=\"position:relative;\"><a href=\"#rokt-embedded-placeholders\" aria-label=\"rokt embedded placeholders permalink\" class=\"anchor before\"><svg width=\"16px\" height=\"17px\" viewBox=\"0 0 16 17\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n                <g id=\"Symbols\" stroke=\"none\" stroke-width=\"1\" fill=\"none\" fill-rule=\"evenodd\">\n                    <g id=\"Icon/Link\" fill=\"#98A0A3\" fill-rule=\"nonzero\">\n                        <g id=\"link\">\n                            <path d=\"M9.5,12.4 C9.6,12.4 9.7,12.4 9.9,12.4 C9.8,12.5 9.8,12.5 9.7,12.6 L7.5,14.8 C5.8,16.5 3,16.5 1.3,14.8 C-0.4,13.1 -0.4,10.3 1.3,8.6 L3.5,6.4 C3.6,6.3 3.6,6.3 3.7,6.2 C5,5 6.9,4.8 8.4,5.5 C8.8,5.7 9.3,6 9.6,6.4 C10,6.7 10.2,7.2 10.5,7.6 C10.2,7.9 9.9,8 9.5,8 C9.4,8 9.2,8 9.1,7.9 C8.9,7.5 8.5,7.2 8.1,6.9 C7,6.2 5.5,6.4 4.5,7.3 L3.8,8 L2.3,9.5 C1.2,10.6 1.2,12.5 2.3,13.6 C3.4,14.7 5.3,14.7 6.4,13.6 L7.9,12.1 C8.4,12.3 8.9,12.4 9.5,12.4 Z M14.7,1.3 C13,-0.4 10.2,-0.4 8.5,1.3 L6.3,3.5 C6.2,3.6 6.2,3.6 6.1,3.7 C6.7,3.7 7.4,3.7 8,3.9 L9.5,2.4 C10.6,1.3 12.5,1.3 13.6,2.4 C14.7,3.5 14.7,5.4 13.6,6.5 L12.1,8 L11.4,8.7 C10.4,9.7 8.9,9.8 7.8,9.1 C7.4,8.9 7.1,8.5 6.8,8.1 C6.7,8.1 6.5,8 6.4,8 C6,8 5.6,8.2 5.4,8.4 C5.6,8.8 5.9,9.3 6.3,9.6 C6.6,10 7.1,10.2 7.5,10.5 C9,11.2 10.9,11 12.3,9.8 C12.4,9.7 12.4,9.7 12.5,9.6 L14.7,7.4 C16.4,5.7 16.4,3 14.7,1.3 Z\" id=\"Shape\"></path>\n                        </g>\n                    </g>\n                </g>\n            </svg></a>Rokt embedded placeholders</h2>\n<p><code class=\"language-text\">MParticle.Rokt.selectPlacements</code> now accepts <code class=\"language-text\">placeholders?: string[]</code>. Each entry must match the <code class=\"language-text\">placeholderName</code> of a <code class=\"language-text\">RoktLayoutView</code>. The previous map of placeholder names to <code class=\"language-text\">findNodeHandle</code> node handles has been removed on both iOS and Android. Version <strong>3.4.0</strong> supports both forms, so you can migrate to names before upgrading to 4.x.</p>\n<p>Before, with a node-handle map:</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre style=\"counter-reset: linenumber NaN\" class=\"language-jsx line-numbers\"><code class=\"language-jsx\"><span class=\"token keyword\">import</span> React<span class=\"token punctuation\">,</span> <span class=\"token punctuation\">{</span> useRef <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'react'</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">import</span> <span class=\"token punctuation\">{</span> findNodeHandle<span class=\"token punctuation\">,</span> View <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'react-native'</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">import</span> MParticle <span class=\"token keyword\">from</span> <span class=\"token string\">'react-native-mparticle'</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token keyword\">function</span> <span class=\"token function\">EmbeddedPlacement</span><span class=\"token punctuation\">(</span><span class=\"token parameter\"><span class=\"token punctuation\">{</span> email<span class=\"token punctuation\">,</span> firstname <span class=\"token punctuation\">}</span></span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">const</span> placeholderRef <span class=\"token operator\">=</span> <span class=\"token function\">useRef</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">null</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token keyword\">const</span> <span class=\"token function-variable function\">onPlaceholderLayout</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">const</span> attributes <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span> email<span class=\"token punctuation\">,</span> firstname <span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n    MParticle<span class=\"token punctuation\">.</span>Rokt<span class=\"token punctuation\">.</span><span class=\"token function\">selectPlacements</span><span class=\"token punctuation\">(</span><span class=\"token string\">'RoktExperience'</span><span class=\"token punctuation\">,</span> attributes<span class=\"token punctuation\">,</span> <span class=\"token punctuation\">{</span>\n      Location1<span class=\"token operator\">:</span> <span class=\"token function\">findNodeHandle</span><span class=\"token punctuation\">(</span>placeholderRef<span class=\"token punctuation\">.</span>current<span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token keyword\">return</span> <span class=\"token punctuation\">(</span>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span><span class=\"token class-name\">View</span></span> <span class=\"token attr-name\">onLayout</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span>onPlaceholderLayout<span class=\"token punctuation\">}</span></span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\">\n      </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span><span class=\"token class-name\">MParticle.RoktLayoutView</span></span> <span class=\"token attr-name\">ref</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span>placeholderRef<span class=\"token punctuation\">}</span></span> <span class=\"token attr-name\">placeholderName</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>Location1<span class=\"token punctuation\">\"</span></span> <span class=\"token punctuation\">/></span></span><span class=\"token plain-text\">\n    </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span><span class=\"token class-name\">View</span></span><span class=\"token punctuation\">></span></span>\n  <span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code><span aria-hidden=\"true\" class=\"line-numbers-rows\" style=\"white-space: normal; width: auto; left: 0;\"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></pre></div>\n<p>After, with placeholder names:</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre style=\"counter-reset: linenumber NaN\" class=\"language-jsx line-numbers\"><code class=\"language-jsx\"><span class=\"token keyword\">import</span> React<span class=\"token punctuation\">,</span> <span class=\"token punctuation\">{</span> useEffect <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'react'</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">import</span> MParticle <span class=\"token keyword\">from</span> <span class=\"token string\">'react-native-mparticle'</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token keyword\">function</span> <span class=\"token function\">EmbeddedPlacement</span><span class=\"token punctuation\">(</span><span class=\"token parameter\"><span class=\"token punctuation\">{</span> email<span class=\"token punctuation\">,</span> firstname <span class=\"token punctuation\">}</span></span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token function\">useEffect</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">const</span> attributes <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span> email<span class=\"token punctuation\">,</span> firstname <span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n    MParticle<span class=\"token punctuation\">.</span>Rokt<span class=\"token punctuation\">.</span><span class=\"token function\">selectPlacements</span><span class=\"token punctuation\">(</span><span class=\"token string\">'RoktExperience'</span><span class=\"token punctuation\">,</span> attributes<span class=\"token punctuation\">,</span> <span class=\"token punctuation\">[</span><span class=\"token string\">'Location1'</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">[</span>email<span class=\"token punctuation\">,</span> firstname<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token keyword\">return</span> <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span><span class=\"token class-name\">MParticle.RoktLayoutView</span></span> <span class=\"token attr-name\">placeholderName</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>Location1<span class=\"token punctuation\">\"</span></span> <span class=\"token punctuation\">/></span></span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code><span aria-hidden=\"true\" class=\"line-numbers-rows\" style=\"white-space: normal; width: auto; left: 0;\"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></pre></div>\n<p>This example selects placements on mount and when the <code class=\"language-text\">email</code> or <code class=\"language-text\">firstname</code> string changes. Build the attributes object inside the effect and include each value it uses in the dependency list. If you instead depend on an <code class=\"language-text\">attributes</code> object passed by a parent, keep that object referentially stable (for example, with <code class=\"language-text\">useMemo</code>) so unrelated renders do not send another placement request.</p>\n<p>Remove the ref, <code class=\"language-text\">findNodeHandle</code> import, and any <code class=\"language-text\">onLayout</code> handler or timer used to wait for the view to mount. The named view can mount after the request starts.</p>\n<p>For overlays, omit the placeholders argument. If you pass a configuration as the fourth argument, use <code class=\"language-text\">undefined</code> for placeholders:</p>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre style=\"counter-reset: linenumber NaN\" class=\"language-javascript line-numbers\"><code class=\"language-javascript\">MParticle<span class=\"token punctuation\">.</span>Rokt<span class=\"token punctuation\">.</span><span class=\"token function\">selectPlacements</span><span class=\"token punctuation\">(</span><span class=\"token string\">'RoktOverlay'</span><span class=\"token punctuation\">,</span> attributes<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token keyword\">const</span> config <span class=\"token operator\">=</span> MParticle<span class=\"token punctuation\">.</span>Rokt<span class=\"token punctuation\">.</span><span class=\"token function\">createRoktConfig</span><span class=\"token punctuation\">(</span><span class=\"token string\">'system'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\nMParticle<span class=\"token punctuation\">.</span>Rokt<span class=\"token punctuation\">.</span><span class=\"token function\">selectPlacements</span><span class=\"token punctuation\">(</span><span class=\"token string\">'RoktOverlay'</span><span class=\"token punctuation\">,</span> attributes<span class=\"token punctuation\">,</span> <span class=\"token keyword\">undefined</span><span class=\"token punctuation\">,</span> config<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code><span aria-hidden=\"true\" class=\"line-numbers-rows\" style=\"white-space: normal; width: auto; left: 0;\"><span></span><span></span><span></span><span></span></span></pre></div>\n<p>TypeScript rejects the old map. If plain JavaScript passes a map, the SDK logs an error and sends the request without embedded views. An empty object (<code class=\"language-text\">{}</code>) is also a map; use an omitted argument or <code class=\"language-text\">undefined</code> for overlays.</p>\n<p>Check these behaviors after migration:</p>\n<ul>\n<li>A placeholder that has not mounted delays the request by up to <strong>2 seconds</strong>. A misspelled or never-rendered name logs <code class=\"language-text\">Cannot resolve placeholder</code>; the request proceeds with the views available when the wait ends.</li>\n<li>If <code class=\"language-text\">MParticle.Rokt.close()</code> runs, or a newer call with the same identifier supersedes a pending request before its placeholders mount, the waiting call emits <code class=\"language-text\">PlacementFailure</code>.</li>\n</ul>\n<p>Follow the <a href=\"https://docs.rokt.com/integration-guides/ecommerce/sdk/react-native/#placement-rn\">Rokt placement guide</a> for complete placement and event-handling examples.</p>\n<h2 id=\"android\" style=\"position:relative;\"><a href=\"#android\" aria-label=\"android permalink\" class=\"anchor before\"><svg width=\"16px\" height=\"17px\" viewBox=\"0 0 16 17\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n                <g id=\"Symbols\" stroke=\"none\" stroke-width=\"1\" fill=\"none\" fill-rule=\"evenodd\">\n                    <g id=\"Icon/Link\" fill=\"#98A0A3\" fill-rule=\"nonzero\">\n                        <g id=\"link\">\n                            <path d=\"M9.5,12.4 C9.6,12.4 9.7,12.4 9.9,12.4 C9.8,12.5 9.8,12.5 9.7,12.6 L7.5,14.8 C5.8,16.5 3,16.5 1.3,14.8 C-0.4,13.1 -0.4,10.3 1.3,8.6 L3.5,6.4 C3.6,6.3 3.6,6.3 3.7,6.2 C5,5 6.9,4.8 8.4,5.5 C8.8,5.7 9.3,6 9.6,6.4 C10,6.7 10.2,7.2 10.5,7.6 C10.2,7.9 9.9,8 9.5,8 C9.4,8 9.2,8 9.1,7.9 C8.9,7.5 8.5,7.2 8.1,6.9 C7,6.2 5.5,6.4 4.5,7.3 L3.8,8 L2.3,9.5 C1.2,10.6 1.2,12.5 2.3,13.6 C3.4,14.7 5.3,14.7 6.4,13.6 L7.9,12.1 C8.4,12.3 8.9,12.4 9.5,12.4 Z M14.7,1.3 C13,-0.4 10.2,-0.4 8.5,1.3 L6.3,3.5 C6.2,3.6 6.2,3.6 6.1,3.7 C6.7,3.7 7.4,3.7 8,3.9 L9.5,2.4 C10.6,1.3 12.5,1.3 13.6,2.4 C14.7,3.5 14.7,5.4 13.6,6.5 L12.1,8 L11.4,8.7 C10.4,9.7 8.9,9.8 7.8,9.1 C7.4,8.9 7.1,8.5 6.8,8.1 C6.7,8.1 6.5,8 6.4,8 C6,8 5.6,8.2 5.4,8.4 C5.6,8.8 5.9,9.3 6.3,9.6 C6.6,10 7.1,10.2 7.5,10.5 C9,11.2 10.9,11 12.3,9.8 C12.4,9.7 12.4,9.7 12.5,9.6 L14.7,7.4 C16.4,5.7 16.4,3 14.7,1.3 Z\" id=\"Shape\"></path>\n                        </g>\n                    </g>\n                </g>\n            </svg></a>Android</h2>\n<p>Native Android initialization continues as before. The wrapper supplies its required <code class=\"language-text\">android-core</code> dependency automatically. Apps using <code class=\"language-text\">MParticle.Rokt.*</code> or <code class=\"language-text\">RoktLayoutView</code> must also declare the matching Rokt kit, which is not bundled by the wrapper:</p>\n<div class=\"gatsby-highlight\" data-language=\"groovy\"><pre style=\"counter-reset: linenumber NaN\" class=\"language-groovy line-numbers\"><code class=\"language-groovy\">implementation <span class=\"token string\">'com.mparticle:android-rokt-kit:COMPATIBLE_VERSION_OR_RANGE'</span></code><span aria-hidden=\"true\" class=\"line-numbers-rows\" style=\"white-space: normal; width: auto; left: 0;\"><span></span></span></pre></div>\n<p>Replace <code class=\"language-text\">COMPATIBLE_VERSION_OR_RANGE</code> with the <code class=\"language-text\">android-rokt-kit</code> version or range declared in <code class=\"language-text\">node_modules/react-native-mparticle/android/build.gradle</code> for your installed wrapper release (<a href=\"https://github.com/mParticle/react-native-mparticle/blob/main/android/build.gradle\">source</a>). With Expo, use <code class=\"language-text\">&quot;androidKits&quot;: [&quot;android-rokt-kit&quot;]</code> in the plugin options; the plugin adds the kit dependency.</p>\n<p>The Rokt kit requires <code class=\"language-text\">compileSdk</code> <strong>35+</strong> and Android Gradle Plugin <strong>8.6+</strong>. Apply the <a href=\"#rokt-embedded-placeholders\">placeholder migration</a> on Android as well. Shoppable Ads remains iOS only.</p>","frontmatter":{"title":"Upgrade to Version 4","order":3,"seoTitle":null,"seoDescription":null},"parent":{"__typename":"File","modifiedTime":"October 27, 2026"}}},"pageContext":{"slug":"/developers/client-sdks/react-native/upgrade-to-version-4/"}},"staticQueryHashes":["159144251"]}