Version: 7.11.0

Styling with options

A Screen's look and feel is configured with an Options object. Options can be applied to screens in three ways. Each method of applying options has benefits and draw backs which are important be aware of so we can use the right tool for the job.

Command options

Options can be passed to layouts as part of a command. For example when pushing a screen. Options passed in commands are typically dynamic options which are determined at runtime.

In the example below we're pushing a user profile screen and we'd like show the user name in the title. To do so, we set the title in the component's options.

import { Navigation } from 'react-native-navigation';
function showUserProfileScreen(user: User) {
Navigation.push(componentId, {
component: {
name: 'ProfileScreen',
passProps: { user },
options: {
topBar: {
title: {
text: user.name,
},
},
},
},
});
}

Notice how the title is actually inferred from the user object which is set in passProps. While this works perfectly fine, declaring the title each time a screen is pushed is a bit tedious and error prone. Later on we'll see a more convenient method to declare dynamic options which are inferred from props.

Static options

Static options are options that are declared statically on the component class. Whenever a screen has a known predefined style, static options should be used as they are evaluated immediately when the screen is created.

import { NavigationComponent, Options } from 'react-native-navigation';
class MyScreen extends NavigationComponent {
static options: Options = {
topBar: {
title: {
text: 'My Screen',
},
},
};
}

Handle props in static options

Sometimes a screen's style includes properties defined in the calling scope where the screen is used. Like in the user profile screen we've seen above where the the user name is used as the TopBar title. As the user name is unique for each profile, it can't be defined explicitly in the static options.

Luckily, we can access props from static options and set the title from static options! Let's see how this is done:

import { NavigationComponent, NavigationComponentProps, Options } from 'react-native-navigation';
interface Props extends NavigationComponentProps {
order: OrderDetails;
}
class OrderScreen extends NavigationComponent<Props> {
static options(props: Props): Options {
return {
topBar: {
title: {
text: props.order.orderId,
},
},
};
}
}

Following this approach we can determine options that are dependent on other external factors, such as experiments or A/B tests.

import { NavigationComponent, Options } from 'react-native-navigation';
class ExperimentScreen extends NavigationComponent {
static options(): Options {
const ExperimentsManager = require('./ExperimentsManager');
const food = ExperimentsManager.isActive('VeganExperiment') ? 'Tofu' : 'Hamburger';
return {
topBar: {
title: {
text: `Hello ${food}!`,
},
},
};
}
}

Merge options

The mergeOptions command is used to update a layout's style. Keep in mind that the merge happens in native, and not ins JS. This meaning that if mergeOptions is called to update a screen's options, the static options declared on the React Component are not affected by mergeOptions.

The following example shows how to update a TopBar background color to red.

import { Navigation } from 'react-native-navigation';
Navigation.mergeOptions(componentId, {
topBar: {
background: {
color: 'red',
},
},
});

warning

Avoid using mergeOptions in a screen's constructor or in componentDidMount!

When a screen first appears, it's constructor and componentDidMount functions are called followed by a componentDidAppear event. (read more about screen lifecycle here).

Developers might be tempted to call mergeOptions in constructor or componentDidMount to update options. Calling mergeOptions before the componentDidAppear event has been received has two very negative effects:

  1. Updating certain options can trigger additional layout and draw cycles which can have serious impact on performance.
  2. Options applied dynamically with the mergeOptions command might be handled in native after the screen has already appeared. This will result in noticeable flickering and artifacts as options are updated after the initial options have been applied and are visible to the user.