1--- 2title: Use Search Parameters 3description: Learn how to access and modify search parameters in your app. 4sidebar_title: Search Parameters 5--- 6 7import { FileTree } from '~/ui/components/FileTree'; 8import { Terminal } from '~/ui/components/Snippet'; 9import { Step } from '~/ui/components/Step'; 10 11Search parameters (also known as query params) are serializable fields that can be added to a URL. They are commonly used to pass data between pages. Expo Router provides hooks for accessing and modifying these parameters. 12 13In nested apps, you'll often have **multiple pages mounted** at the same time. For example, a stack has the previous page and current page in memory when a new route is pushed. Because of this, Expo Router provides two different hooks for accessing search parameters: 14 15- **useLocalSearchParams**: Returns the search parameters for the current component. It only updates when the global URL conforms to the route. 16- **useGlobalSearchParams**: Returns the global URL regardless of the component. It updates on every search param change and might cause components to update extraneously in the background. 17 18Both hooks are typed and accessed the same way. However, the only difference is how frequently they update. Consider the following example: 19 20## Local vs. global search parameters 21 22The example below demonstrates the difference between `useLocalSearchParams` and `useGlobalSearchParams`. It uses the following **app** directory structure: 23 24<FileTree files={['app/_layout.js', 'app/index.js', 'app/[user].js']} /> 25 26<Step label="1"> 27 28 The Root Layout is a stack navigator: 29 30 ```jsx app/_layout.js 31 import { Stack } from 'expo-router'; 32 33 export default function Layout() { 34 return <Stack />; 35 } 36 ``` 37 38</Step> 39 40<Step label="2"> 41 42 The initial route redirects to the dynamic route **app/[user].js**, with **user=evanbacon**: 43 44 ```jsx app/index.js 45 import { Redirect } from 'expo-router'; 46 47 export default function Route() { 48 return <Redirect href="/evanbacon" />; 49 } 50 ``` 51 52</Step> 53 54<Step label="3"> 55 56 The dynamic route **app/[user]** prints out the global and local search parameters. It also allows for pushing new instances of the same route with different search parameters: 57 58 ```jsx app/[user].js 59 import { Text, View } from 'react-native'; 60 import { useLocalSearchParams, useGlobalSearchParams, Link } from 'expo-router'; 61 62 const friends = ['charlie', 'james'] 63 64 export default function Route() { 65 const glob = useGlobalSearchParams(); 66 const local = useLocalSearchParams(); 67 68 console.log("Local:", local.user, "Global:", glob.user); 69 70 return ( 71 <View> 72 <Text>User: {local.user}</Text> 73 {friends.map(friend => ( 74 <Link key={friend} href={`/${friend}`}> 75 Visit {friend} 76 </Link> 77 ))} 78 </View> 79 ); 80 } 81 ``` 82 83</Step> 84 85<Step label="4"> 86 87When the app starts, the following log is printed: 88 89<Terminal cmd={['Local: evanbacon Global: evanbacon']} /> 90 91Pressing "Visit charlie" pushes a new instance of `/[user]` with **user=charlie**, and logs the following: 92 93<Terminal 94 cmd={[ 95 '# This log came from the new screen', 96 'Local: charlie Global: charlie', 97 '# This log came from the first screen', 98 'Local: evanbacon Global: charlie', 99 ]} 100/> 101 102Pressing "Visit james" has a similar effect: 103 104<Terminal 105 cmd={[ 106 '# This log came from the new, "/james" screen', 107 'Local: james Global: james', 108 '# This log came from the "/evanbacon" screen', 109 'Local: evanbacon Global: james', 110 '# This log came from the "/charlie" screen', 111 'Local: charlie Global: james', 112 ]} 113/> 114 115 **Results:** 116 117 - `useGlobalSearchParams` made the background screens re-render when the search params changed. It can cause performance issues if overused. 118 - Global re-renders are executed in order of the stack, so the first screen is re-rendered first, then the **user=charlie** screen is re-rendered after. 119 - `useLocalSearchParams` remained the same, even when the global search params changed. You can leverage this behavior for data fetching to ensure the previous screen's data is still available when you navigate back. 120 121</Step> 122 123## Statically-typed Search Parameters 124 125Both the `useLocalSearchParams` and `useGlobalSearchParams` can be statically typed using a generic: 126 127```tsx app/search.tsx 128import { Text } from 'react-native'; 129import { useLocalSearchParams } from 'expo-router'; 130 131export default function Route() { 132 const { user } = useLocalSearchParams<{ user: string }>(); 133 134 return <Text>User: {user}</Text>; 135} 136``` 137 138Any additional search parameters are to be typed optionally: 139 140```tsx 141const { user, query } = useLocalSearchParams<{ user: string; query?: string }>(); 142``` 143 144When used with the rest syntax (`...`), implements a string array: 145 146```tsx app/[...everything].tsx 147import { Text } from 'react-native'; 148import { useLocalSearchParams } from 'expo-router'; 149 150export default function Route() { 151 const { user } = useLocalSearchParams<{ 152 /* @info <b>everything</b> will be an array of path segments, even if there's only one */ 153 everything: string[]; 154 /* @end */ 155 }>(); 156 157 return <Text>User: {user}</Text>; 158} 159``` 160 161## Updating Search Parameters 162 163Search parameters can be updated using the **router.setParams** function from the imperative API. The following example uses a `<TextInput>` to update the search parameter **q**. This action will not push anything new to the history stack. 164 165```tsx app/search.tsx 166import { useLocalSearchParams, router } from 'expo-router'; 167import React from 'react'; 168import { TextInput, View } from 'react-native'; 169 170export default function Page() { 171 const params = useLocalSearchParams<{ q?: string }>(); 172 const [search, setSearch] = React.useState(params.q); 173 174 return ( 175 <TextInput 176 value={search} 177 onChangeText={search => { 178 setSearch(search); 179 /* @info Set the search parameter <b>q</b> to the text input <b>search</b> */ 180 router.setParams({ q: search }); 181 /* @end */ 182 }} 183 placeholderTextColor="#A0A0A0" 184 placeholder="Search" 185 style={{ 186 borderRadius: 12, 187 backgroundColor: '#fff', 188 fontSize: 24, 189 color: '#000', 190 margin: 12, 191 padding: 16, 192 }} 193 /> 194 ); 195} 196``` 197