Skip to content

Commit bb99fa2

Browse files
committed
Document changes related to preload and icons
1 parent 3170c19 commit bb99fa2

File tree

4 files changed

+96
-96
lines changed

4 files changed

+96
-96
lines changed

versioned_docs/version-8.x/bottom-tab-navigator.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -519,7 +519,7 @@ tabBarLabelStyle: {
519519

520520
#### `tabBarIcon`
521521

522-
Function that given `{ focused: boolean, color: string, size: number }` returns an icon to display in the tab bar. It can be one of the following:
522+
Icon object to display or a function that given `{ focused: boolean, color: string, size: number }` returns an icon to display in the tab bar. It can be one of the following:
523523

524524
- An icon object with both `native` and `custom` implementations
525525
- A React element with `custom` implementation only

versioned_docs/version-8.x/navigation-actions.md

Lines changed: 1 addition & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -525,33 +525,7 @@ Depending on the navigator, `preload` may work differently:
525525
- In a stack navigator ([stack](stack-navigator.md), [native stack](native-stack-navigator.md)), the screen will be rendered off-screen and animated in when you navigate to it. If [`getId`](screen.md#id) is specified, it'll be used for the navigation to identify the preloaded screen.
526526
- In a tab or drawer navigator ([bottom tabs](bottom-tab-navigator.md), [material top tabs](material-top-tab-navigator.md), [drawer](drawer-navigator.md), etc.), the existing screen will be rendered as if `lazy` was set to `false`. Calling `preload` on a screen that is already rendered will not have any effect.
527527

528-
When a screen is preloaded in a stack navigator, it will have a few limitations:
529-
530-
- It can't dispatch navigation actions (e.g. `navigate`, `goBack`, etc.).
531-
- It can't update options with `navigation.setOptions`.
532-
- It can't listen to events from the navigator (e.g. `focus`, `tabPress`, etc.).
533-
534-
The `navigation` object will be updated once you navigate to the screen. So if you have an event listener in a `useEffect` hook, and have a dependency on `navigation`, it will add any listeners when the screen is navigated to:
535-
536-
```js
537-
React.useEffect(() => {
538-
const unsubscribe = navigation.addListener('tabPress', () => {
539-
// do something
540-
});
541-
542-
return () => {
543-
unsubscribe();
544-
};
545-
}, [navigation]);
546-
```
547-
548-
Similarly, for dispatching actions or updating options, you can check if the screen is focused before doing so:
549-
550-
```js
551-
if (navigation.isFocused()) {
552-
navigation.setOptions({ title: 'Updated title' });
553-
}
554-
```
528+
When a screen is preloaded in a stack navigator, it can't dispatch navigation actions (e.g. `navigate`, `goBack`, etc.) until it becomes active.
555529

556530
### setParams
557531

versioned_docs/version-8.x/navigation-object.md

Lines changed: 1 addition & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -914,33 +914,7 @@ Depending on the navigator, `preload` may work slightly differently:
914914
- In a stack navigator ([stack](stack-navigator.md), [native stack](native-stack-navigator.md)), the screen will be rendered off-screen and animated in when you navigate to it. If [`getId`](screen.md#id) is specified, it'll be used for the navigation to identify the preloaded screen.
915915
- In a tab or drawer navigator ([bottom tabs](bottom-tab-navigator.md), [material top tabs](material-top-tab-navigator.md), [drawer](drawer-navigator.md), etc.), the existing screen will be rendered as if `lazy` was set to `false`. Calling `preload` on a screen that is already rendered will not have any effect.
916916

917-
When a screen is preloaded in a stack navigator, it will have a few limitations:
918-
919-
- It can't dispatch navigation actions (e.g. `navigate`, `goBack`, etc.).
920-
- It can't update options with `navigation.setOptions`.
921-
- It can't listen to events from the navigator (e.g. `focus`, `tabPress`, etc.).
922-
923-
The `navigation` object will be updated once you navigate to the screen. So if you have an event listener in a `useEffect` hook, and have a dependency on `navigation`, it will add any listeners when the screen is navigated to:
924-
925-
```js
926-
React.useEffect(() => {
927-
const unsubscribe = navigation.addListener('tabPress', () => {
928-
// do something
929-
});
930-
931-
return () => {
932-
unsubscribe();
933-
};
934-
}, [navigation]);
935-
```
936-
937-
Similarly, for dispatching actions or updating options, you can check if the screen is focused before doing so:
938-
939-
```js
940-
if (navigation.isFocused()) {
941-
navigation.setOptions({ title: 'Updated title' });
942-
}
943-
```
917+
When a screen is preloaded in a stack navigator, it can't dispatch navigation actions (e.g. `navigate`, `goBack`, etc.) until it becomes active.
944918

945919
### `setParams`
946920

versioned_docs/version-8.x/upgrading-from-7.x.md

Lines changed: 93 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ Each navigator exports its own helper function, e.g. `createNativeStackScreen` f
157157

158158
:::note
159159

160-
This is not a breaking change. It's not required to use this API and your existing code will continue to work as before. You can incrementally adopt this API for new screens to get proper types for `route` object in various callbacks such as `options`, `listeners`, etc.
160+
This is technically not a breaking change. It's not required to use this API and your existing code will continue to work as before. You can incrementally adopt this API for new screens to get proper types for `route` object in various callbacks such as `options`, `listeners`, etc.
161161

162162
:::
163163

@@ -279,7 +279,7 @@ As part of this change, some of the options have changed to work with native tab
279279
- `"labeled"` - same as `tabBarShowLabel: true`
280280
- `"unlabeled"` - same as `tabBarShowLabel: false`
281281
- `tabBarLabel` now only accepts a `string`
282-
- `tabBarIcon` now accepts an function that can return an icon object, returning a react element still works with `custom` implementation
282+
- `tabBarIcon` now accepts an icon object or function that can return an icon object, returning a react element still works with `custom` implementation - so you don't need to change anything if you're using `custom` implementation.
283283

284284
The following props have been removed:
285285

@@ -325,6 +325,35 @@ createBottomTabNavigator({
325325
</TabItem>
326326
</Tabs>
327327

328+
#### Preloaded screens now behave differently
329+
330+
Previously, when a screen was preloaded in Stack and Native Stack Navigators, there were a few restrictions:
331+
332+
- Options could not be updated with [`setOptions`](navigation-object.md#setoptions) until the screen became active.
333+
- Adding listeners with [`addListener`](navigation-object.md#navigation-events) did nothing until the screen became active.
334+
- Preloaded screens could not contain nested navigators.
335+
336+
In addition, the `navigation` object received by preloaded screens was different from that of active screens. So it resulted in re-rendering the screen when it became active.
337+
338+
We have reworked the implementation of preloaded screens to make it more consistent with active screens:
339+
340+
- Options can now be updated with `setOptions` even when the screen is preloaded.
341+
- Listeners added with `addListener` will now be called even when the screen is preloaded.
342+
- Preloaded screens can now contain nested navigators.
343+
- The `navigation` object now does not change when the screen becomes active.
344+
345+
While this is a breaking change, your existing code will likely continue to work as before if you were not relying on any of the special behaviors of preloaded screens for your logic.
346+
347+
If your existing code checked `navigation.isFocused()` before calling `setOptions`, it will continue to work as before. However, you can now simplify such code by removing the check:
348+
349+
```diff lang=js
350+
- if (navigation.isFocused()) {
351+
navigation.setOptions({ title: 'New Title' });
352+
- }
353+
```
354+
355+
See [`navigation.preload`](navigation-object.md#preload) for usage details.
356+
328357
#### Navigators no longer accept an `id` prop
329358

330359
Previously, navigators accepted an `id` prop to identify them - which was used with `navigation.getParent(id)` to get a parent navigator by id. However, there were a couple of issues with this approach:
@@ -773,45 +802,6 @@ const MyStack = createNativeStackNavigator({
773802

774803
See [`Navigator` docs](navigator.md#router) for more details.
775804

776-
### `Header` from `@react-navigation/elements` has been reworked
777-
778-
The `Header` component from `@react-navigation/elements` has been reworked with various improvements:
779-
780-
- It uses the new liquid glass effect on iOS 26
781-
- It supports `ColorValue` and CSS custom properties for colors
782-
- It supports `headerBlurEffect` on Web (previously only supported on iOS in Native Stack Navigator)
783-
- It no longer needs the layout of the screen to render correctly
784-
785-
To match the iOS 26 design, the back button title is no longer shown by default on iOS 26.
786-
787-
See [Elements](elements.md) for more details.
788-
789-
### `react-native-tab-view` now supports a `renderAdapter` prop for custom adapters
790-
791-
By default, `react-native-tab-view` uses [`react-native-pager-view`](https://github.com/callstack/react-native-pager-view) for rendering pages on Android and iOS. However, it may not be suitable for all use cases.
792-
793-
So it now supports a `renderAdapter` prop to provide a custom adapter for rendering pages. For example, you can use `ScrollViewAdapter` to use a `ScrollView` for rendering pages:
794-
795-
```js
796-
import React from 'react';
797-
import { TabView, ScrollViewAdapter } from 'react-native-tab-view';
798-
799-
export default function TabViewExample() {
800-
const [index, setIndex] = React.useState(0);
801-
802-
return (
803-
<TabView
804-
navigationState={{ index, routes }}
805-
renderScene={renderScene}
806-
onIndexChange={setIndex}
807-
renderAdapter={ScrollViewAdapter}
808-
/>
809-
);
810-
}
811-
```
812-
813-
You can also create your own custom adapter by implementing the required interface. See the [`react-native-tab-view` docs](tab-view.md) for more information.
814-
815805
### State persistence is simplified with the `persistor` prop
816806

817807
Previously, state persistence could be implemented with `initialState` and `onStateChange` props, however it required some boilerplates and handling edge cases.
@@ -874,3 +864,65 @@ export default function App() {
874864
</Tabs>
875865

876866
See [State persistence docs](state-persistence.md) for more details.
867+
868+
### `Header` from `@react-navigation/elements` has been reworked
869+
870+
The `Header` component from `@react-navigation/elements` has been reworked with various improvements:
871+
872+
- It uses the new liquid glass effect on iOS 26
873+
- It supports `ColorValue` and CSS custom properties for colors
874+
- It supports `headerBlurEffect` on Web (previously only supported on iOS in Native Stack Navigator)
875+
- It no longer needs the layout of the screen to render correctly
876+
877+
To match the iOS 26 design, the back button title is no longer shown by default on iOS 26.
878+
879+
See [Elements](elements.md) for more details.
880+
881+
### Bottom Tab Navigator now supports Material Symbols & SF Symbols icons
882+
883+
The Bottom Tab Navigator now supports using [Material Symbols](https://fonts.google.com/icons) on Android and [SF Symbols](https://developer.apple.com/sf-symbols/) on iOS for tab bar icons.
884+
885+
You can specify the icon as an object in `tabBarIcon` option:
886+
887+
```js
888+
tabBarIcon: Platform.select({
889+
ios: {
890+
type: 'sfSymbol',
891+
name: 'house',
892+
},
893+
android: {
894+
type: 'materialSymbol',
895+
name: 'home',
896+
},
897+
}),
898+
```
899+
900+
This is supported both in `native` and `custom` implementations of Bottom Tab Navigator.
901+
902+
See [Bottom Tab Navigator docs](bottom-tab-navigator.md#tabbaricon) for more details.
903+
904+
### `react-native-tab-view` now supports a `renderAdapter` prop for custom adapters
905+
906+
By default, `react-native-tab-view` uses [`react-native-pager-view`](https://github.com/callstack/react-native-pager-view) for rendering pages on Android and iOS. However, it may not be suitable for all use cases.
907+
908+
So it now supports a `renderAdapter` prop to provide a custom adapter for rendering pages. For example, you can use `ScrollViewAdapter` to use a `ScrollView` for rendering pages:
909+
910+
```js
911+
import React from 'react';
912+
import { TabView, ScrollViewAdapter } from 'react-native-tab-view';
913+
914+
export default function TabViewExample() {
915+
const [index, setIndex] = React.useState(0);
916+
917+
return (
918+
<TabView
919+
navigationState={{ index, routes }}
920+
renderScene={renderScene}
921+
onIndexChange={setIndex}
922+
renderAdapter={ScrollViewAdapter}
923+
/>
924+
);
925+
}
926+
```
927+
928+
You can also create your own custom adapter by implementing the required interface. See the [`react-native-tab-view` docs](tab-view.md) for more information.

0 commit comments

Comments
 (0)