React Navigation v6: Unresolved Decision on Nested Navigator Param Merging
0 reputation · 11 Aug 2021, 06:47 UTC
0 reputation · 11 Aug 2021, 06:47 UTC
React Navigation 6 introduced a new Linking configuration that replaces the legacy deep‑link prop format. While the docs detail the structure of prefixes and config, they do not specify how parameters supplied to a nested navigator are propagated to its parent navigator.
In practice, when a deep link targets a screen inside a nested stack, the parameters may either be merged into the parent navigation state or remain scoped to the nested navigator. Concurrent navigation actions (e.g., a push followed immediately by a pop) can exacerbate this ambiguity, potentially leading to race conditions or stale state.
Given the lack of explicit guidance, the following questions need clarification:
getInitialURL and subscribe affect this param propagation during concurrent navigation actions?34775 reputation · 11 Aug 2021, 10:30 UTC
route.params isolated; a deep link that targets a screen inside a nested stack only sets params on that screen.initialParams to the nested screen, the nested screen’s params (including those from the deep link) override any identically‑named keys you passed.getInitialURL and subscribe affect this? These async linking functions only resolve the URL and deliver the parsed params to the target screen’s route.params. They do not trigger any automatic merge with the parent navigator. Concurrent navigation actions (e.g., a push followed by a pop) that occur after the linking resolution behave normally; to avoid race conditions, wait for the linking promise to resolve before dispatching further navigation actions.The design isolates navigators to prevent unintended prop leakage. Automatic merging would couple navigators and make debugging harder, so the library requires explicit opt‑in via initialParams or by passing props when rendering the nested navigator.
Stack.Navigator inside a Tab.Navigator).const { params } = useRoute();.initialParams (or as props) to the nested screen: <Stack.Screen name="Child" initialParams={parentParams} />.useRoute().params.initialParams.If you observe that parent navigation state changes after a deep link, please share your linking configuration (especially any custom getInitialURL or subscribe logic) so we can verify whether an explicit merge is being performed.
Use comments to ask for clarification. Post a solution as an answer.
34,775 reputation · 11 Aug 2021, 10:24 UTC
When a screen inside a nested navigator receives params via navigation.navigate (or a deep link), React Navigation v6 merges those params with the screen’s initialParams defined in the navigator config. The merge is shallow: top‑level keys from the incoming params overwrite those in initialParams, while nested objects are replaced entirely. This merge happens only for the target screen; it does not bubble up to the parent navigator. If you need to suppress the merge, pass merge: false in the navigation options, which causes the incoming params to replace the entire param set.
// Example: nested stack inside a tab navigator
navigation.navigate('ChildScreen', { id: 123 }, { merge: true }); // default
// merge:false replaces initialParams completely
navigation.navigate('ChildScreen', { id: 123 }, { merge: false });