React-native-navigation: Per-screen styling not working [v2]

Created on 4 Apr 2018  路  3Comments  路  Source: wix/react-native-navigation

Issue Description

I'm trying to style the topBar on a per-screen basis using static get options() but it doesn't seem to work. It only displays a blank topBar. However, if I put the styling options in Navigation.setRoot({...}) where the screen is first initialized then the styling does work.

Steps to Reproduce / Code Snippets / Screenshots

The following code in the screen component does not get the title to display:

export default class HomeScreen extends React.Component {
    static get options() {
        return {
          topBar: {
            title: {
              title: 'Activity'
            },
          },
        };
      }
...

However, the following code in App.js does get the title to display:

Navigation.setRoot({
    bottomTabs: {
        children: [{
            stack: {
                children: [{
                    component: {
                        name: "example.HomeScreen"
                    }
                }],
                options: {
                    topBar: {
                        title: {
                            title: "Activity",
                        }
                    },
                    bottomTab: {
                        title: "Home",
                        icon: require("./img/homeIcon/homeIcon.png")
                    }
                }
            }
        },
...

Environment

  • React Native Navigation version: 2.0.2218
  • React Native version: 0.53.3
  • Platform(s) (iOS, Android, or both?): Android
  • Device info (Simulator/Device? OS version? Debug/Release?): Device / Android 8.1.0 / Debug

Most helpful comment

@EliSadaka I faced the same issue when wrap my components to support redux store. You have to link the static options() from your wrapped/internal component. The general idea of wrapper component is detailed in #1642. Example of registerContainer.js:

import React from 'react';
import {Provider} from 'react-redux';
import {Navigation} from 'react-native-navigation';

export default function registerContainer(
    containerName,
    component,
    store,
    Provider,
) {
    const generator = function() {
        const InternalComponent = component;

        return class Scene extends React.Component {
            constructor(props) {
                super(props);
            }

            static options = { // LINKED HERE
                ...InternalComponent.options,
            };

            render() {
                return (
                    <Provider store={store}>
                        <InternalComponent
                            ref="child"
                            {...this.props}
                        />
                    </Provider>
                );
            }
        };
    };

    Navigation.registerComponent(containerName, generator);
}

Now register your components as the following:

import {Provider} from 'react-redux';
import registerContainer from "./registerContainer";
import Identify from "../screens/MyComponent";

// provide your reducers here
const store = createStore(reducers);

registerContainer('MyComponent', MyComponent, store, Provider);

All 3 comments

You have a syntax error, you should pass text inside title

topBar: {
  title: {
    text: "Activity",
  }
}

Will update the documentation

I corrected the syntax error but the title still doesn't display when I try to set it in the screen component. I have the same problem when I try to insert a rightButton into the topBar: if I set it in the setRoot function it works but if I set it in the screen component it doesn't work.

@EliSadaka I faced the same issue when wrap my components to support redux store. You have to link the static options() from your wrapped/internal component. The general idea of wrapper component is detailed in #1642. Example of registerContainer.js:

import React from 'react';
import {Provider} from 'react-redux';
import {Navigation} from 'react-native-navigation';

export default function registerContainer(
    containerName,
    component,
    store,
    Provider,
) {
    const generator = function() {
        const InternalComponent = component;

        return class Scene extends React.Component {
            constructor(props) {
                super(props);
            }

            static options = { // LINKED HERE
                ...InternalComponent.options,
            };

            render() {
                return (
                    <Provider store={store}>
                        <InternalComponent
                            ref="child"
                            {...this.props}
                        />
                    </Provider>
                );
            }
        };
    };

    Navigation.registerComponent(containerName, generator);
}

Now register your components as the following:

import {Provider} from 'react-redux';
import registerContainer from "./registerContainer";
import Identify from "../screens/MyComponent";

// provide your reducers here
const store = createStore(reducers);

registerContainer('MyComponent', MyComponent, store, Provider);
Was this page helpful?
0 / 5 - 0 ratings

Related issues

yayanartha picture yayanartha  路  3Comments

yedidyak picture yedidyak  路  3Comments

nbolender picture nbolender  路  3Comments

bdrobinson picture bdrobinson  路  3Comments

Chipped1 picture Chipped1  路  3Comments