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