You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: versioned_docs/version-7.x/auth-flow.md
+105-45
Original file line number
Diff line number
Diff line change
@@ -81,9 +81,21 @@ function SignInScreen() {
81
81
82
82
Here, for each screen, we have defined a condition using the `if` property which takes a hook. The hook returns a boolean value indicating whether the user is signed in or not. If the hook returns `true`, the screen will be available, otherwise it won't.
83
83
84
-
When `useIsSignedIn` returns `true`, React Navigation will only use the `Home` screen, and when it returns `false`, React Navigation will use the `SignIn` screen. This makes it impossible to navigate to the `Home` when the user is not signed in, and to `SignIn` when the user is signed in.
84
+
This means:
85
85
86
-
The magic happens when the value returned by `useIsSignedin` changes. Let's say, initially `useIsSignedIn` returns `false`. This means that `SignIn` screens is shown. After the user signs in, the return value of `useIsSignedIn` will change to `true`. React Navigation will see that the `SignIn` screen is no longer defined and so it will remove it. Then it'll show the `Home` screen automatically because that's the first screen defined when `useIsSignedIn` returns `true`.
86
+
- When `useIsSignedIn` returns `true`, React Navigation will only use the `Home` screen, since it's the only screen matching the condition.
87
+
- Similarly, when `useIsSignedOut` returns `true`, React Navigation will use the `SignIn` screen.
88
+
89
+
This makes it impossible to navigate to the `Home` when the user is not signed in, and to `SignIn` when the user is signed in.
90
+
91
+
When the values returned by `useIsSignedin` and `useIsSignedOut` change, the screens matching the condition will change:
92
+
93
+
- Let's say, initially `useIsSignedOut` returns `true`. This means that `SignIn` screens is shown.
94
+
- After the user signs in, the return value of `useIsSignedIn` will change to `true` and `useIsSignedOut` will change to `false`, which means:
95
+
- React Navigation will see that the `SignIn` screen is no longer matches the condition, so it will remove the screen.
96
+
- Then it'll show the `Home` screen automatically because that's the first screen available when `useIsSignedIn` returns `true`.
97
+
98
+
The order of the screens matters when there are multiple screens matching the condition. For example, if there are two screens matching `useIsSignedIn`, the first screen will be shown when the condition is `true`.
87
99
88
100
## Define the hooks
89
101
@@ -104,8 +116,7 @@ function useIsSignedIn() {
104
116
}
105
117
106
118
functionuseIsSignedOut() {
107
-
constisSignedIn=React.useContext(SignInContext);
108
-
return!isSignedIn;
119
+
return!useIsSignedIn();
109
120
}
110
121
```
111
122
@@ -152,11 +163,21 @@ function SignInScreen() {
152
163
153
164
Here, we have conditionally defined the screens based on the value of `isSignedIn`.
154
165
155
-
When `isSignedIn` is `true`, React Navigation will only see the `Home` screen, and when it returns `false`, React Navigation will see the `SignIn` screen. This makes it impossible to navigate to the `Home` when the user is not signed in, and to `SignIn` when the user is signed in.
166
+
This means:
167
+
168
+
- When `isSignedIn` is `true`, React Navigation will only see the `Home` screen, since it's the only screen defined based on the condition.
169
+
- Similarly, when `isSignedIn` is `false`, React Navigation will only see the `SignIn` screen.
156
170
157
-
This pattern has been in use by other routing libraries such as React Router for a long time, and is commonly known as "Protected routes". Here, our screens which need the user to be signed in are "protected" and cannot be navigated to by other means if the user is not signed in.
171
+
This makes it impossible to navigate to the `Home` when the user is not signed in, and to `SignIn` when the user is signed in.
158
172
159
-
The magic happens when the value of `isSignedin` changes. Let's say, initially `isSignedIn` returns `false`. This means that `SignIn` screens is shown. After the user signs in, the value of `isSignedIn` will change to `true`. React Navigation will see that the `SignIn` screen is no longer defined and so it will remove it. Then it'll show the `Home` screen automatically because that's the first screen defined when `isSignedIn` is `true`.
173
+
When the value of `isSignedin` changes, the screens defined based on the condition will change:
174
+
175
+
- Let's say, initially `isSignedin` is `false`. This means that `SignIn` screens is shown.
176
+
- After the user signs in, the value of `isSignedin` will change to `true`, which means:
177
+
- React Navigation will see that the `SignIn` screen is no longer defined, so it will remove the screen.
178
+
- Then it'll show the `Home` screen automatically because that's the first screen defined when `isSignedin` returns `true`.
179
+
180
+
The order of the screens matters when there are multiple screens matching the condition. For example, if there are two screens defined based on `isSignedin`, the first screen will be shown when the condition is `true`.
Notice how we have only defined the `Home` and `SignIn` screens here, and not the `SplashScreen`. The `SplashScreen` should be rendered before we render any navigators so that we don't render incorrect screens before we know whether the user is signed in or not.
198
252
199
253
When we use this in our component, it'd look something like this:
200
254
255
+
<TabsgroupId="config"queryString="config">
256
+
<TabItemvalue="static"label="Static"default>
257
+
201
258
```js
202
259
if (isLoading) {
203
260
// We haven't finished checking for the token yet
@@ -213,37 +270,6 @@ return (
213
270
);
214
271
```
215
272
216
-
In the above snippet, `isLoading` means that we're still checking if we have a token. This can usually be done by checking if we have a token in `SecureStore` and validating the token.
217
-
218
-
Next, we're exposing the sign in status via the `SignInContext` so that it's available to the `useIsSignedIn` and `useIsSignedOut` hooks.
219
-
220
-
In the above example, we have one screen for each case. But you could also define multiple screens. For example, you probably want to define password reset, signup, etc screens as well when the user isn't signed in. Similarly for the screens accessible after sign in, you probably have more than one screen. We can use [`groups`](static-configuration.md#groups) to define multiple screens:
221
-
222
-
```js
223
-
constRootStack=createNativeStackNavigator({
224
-
screens: {
225
-
// Common screens
226
-
},
227
-
groups: {
228
-
SignedIn: {
229
-
if: useIsSignedIn,
230
-
screens: {
231
-
Home: HomeScreen,
232
-
Profile: ProfileScreen,
233
-
},
234
-
},
235
-
SignedOut: {
236
-
if: useIsSignedOut,
237
-
screens: {
238
-
SignIn: SignInScreen,
239
-
SignUp: SignUpScreen,
240
-
ResetPassword: ResetPasswordScreen,
241
-
},
242
-
},
243
-
},
244
-
});
245
-
```
246
-
247
273
</TabItem>
248
274
<TabItemvalue="dynamic"label="Dynamic">
249
275
@@ -275,14 +301,49 @@ return (
275
301
);
276
302
```
277
303
304
+
</TabItem>
305
+
</Tabs>
306
+
278
307
In the above snippet, `isLoading` means that we're still checking if we have a token. This can usually be done by checking if we have a token in `SecureStore` and validating the token.
279
308
280
-
The main thing to notice is that we're conditionally defining screens based on these state variables:
309
+
Next, we're exposing the sign in status via the `SignInContext` so that it's available to the `useIsSignedIn` and `useIsSignedOut` hooks.
310
+
311
+
In the above example, we have one screen for each case. But you could also define multiple screens. For example, you probably want to define password reset, signup, etc screens as well when the user isn't signed in. Similarly for the screens accessible after sign in, you probably have more than one screen.
312
+
313
+
<TabsgroupId="config"queryString="config">
314
+
<TabItemvalue="static"label="Static"default>
315
+
316
+
We can use [`groups`](static-configuration.md#groups) to define multiple screens:
317
+
318
+
```js
319
+
constRootStack=createNativeStackNavigator({
320
+
screens: {
321
+
// Common screens
322
+
},
323
+
groups: {
324
+
SignedIn: {
325
+
if: useIsSignedIn,
326
+
screens: {
327
+
Home: HomeScreen,
328
+
Profile: ProfileScreen,
329
+
},
330
+
},
331
+
SignedOut: {
332
+
if: useIsSignedOut,
333
+
screens: {
334
+
SignIn: SignInScreen,
335
+
SignUp: SignUpScreen,
336
+
ResetPassword: ResetPasswordScreen,
337
+
},
338
+
},
339
+
},
340
+
});
341
+
```
281
342
282
-
-`SignIn` screen is only defined if `userToken` is `null` (user is not signed in)
283
-
-`Home` screen is only defined if `userToken` is non-null (user is signed in)
343
+
</TabItem>
344
+
<TabItemvalue="dynamic"label="Dynamic">
284
345
285
-
Here, we're conditionally defining one screen for each case. But you could also define multiple screens. For example, you probably want to define password reset, signup, etc screens as well when the user isn't signed in. Similarly, for the screens accessible after signing in, you probably have more than one screen. We can use [`React.Fragment`](https://react.dev/reference/react/Fragment) or [`Group`](group.md) to define multiple screens:
346
+
We can use [`React.Fragment`](https://react.dev/reference/react/Fragment) or [`Group`](group.md) to define multiple screens:
286
347
287
348
```js
288
349
isSignedIn ? (
@@ -301,7 +362,7 @@ isSignedIn ? (
301
362
302
363
:::tip
303
364
304
-
If you have both your login-related screens and rest of the screens in two different Stack navigators and render them conditionally, we recommend to use a single Stack navigator and place the conditional inside instead of using 2 different navigators. This makes it possible to have a proper transition animation during login/logout.
365
+
Instead of having your login-related screens and rest of the screens in two different Stack navigators and render them conditionally, we recommend to use a single Stack navigator and place the conditional inside. This makes it possible to have a proper transition animation during login/logout.
0 commit comments