React-native-navigation: `Navigation.updateProps` not triggering updates on custom top bar title component

Created on 25 Jul 2020  ·  5Comments  ·  Source: wix/react-native-navigation

Issue Description

I have a custom top bar title containing react-native-snap-carousel Pagination component that I need to update using .updateProps to change the active index. But it does nothing.

Steps to Reproduce / Code Snippets / Screenshots

  1. Create MyCustomTitleComponent
import React from 'react';
import {StyleSheet, Text, View} from 'react-native';

const MyCustomTitleComponent = ({count}) => (
  <View style={styles.container}>
    <Text>{count}</Text>
  </View>
);

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
});

export default MyCustomTitleComponent;
  1. Add two Screens

ScreenOne

import React from 'react';
import {Button, StyleSheet, Text, View} from 'react-native';
import {Navigation} from 'react-native-navigation';

const ScreenOne = ({componentId}) => (
  <View style={styles.container}>
    <Text>Screen One</Text>
    <Button
      onPress={() => {
        Navigation.push(componentId, {
          component: {
            name: 'Screen2',
            options: {
              topBar: {
                title: {
                  component: {
                    name: 'MyCustomTitleComponent',
                    passProps: { count: 1 },
                  },
                },
              },
            },
          },
        });
      }}
      title="Go to screen 2"
    />
  </View>
);

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
});

export default ScreenOne;

ScreenTwo

import React, {useEffect} from 'react';
import {StyleSheet, Text, View} from 'react-native';
import {Navigation} from 'react-native-navigation';

const ScreenTwo = () => {
  useEffect(() => {
    const timeOutId = setTimeout(() => {
      Navigation.updateProps('MyCustomTitleComponent', {
        count: 100,
      });
    }, 3000);

    return () => clearTimeout(timeOutId);
  }, []);

  return (
    <View style={styles.container}>
      <Text>Screen Two</Text>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
});

export default ScreenTwo;


  1. Register screens and set stack root
import {Navigation} from 'react-native-navigation';

Navigation.registerComponent(
  'MyCustomTitleComponent',
  () => MyCustomTitleComponent,
);

Navigation.registerComponent('ScreenOne', () => ScreenOne);
Navigation.registerComponent('ScrenTwo', () => ScrenTwo);

Navigation.events().registerAppLaunchedListener(() => {
  Navigation.setRoot({
    root: {
      stack: {
        children: [
          {
            component: {
              name: 'ScreenOne',
            },
          },
        ],
      },
    },
  });
});


Environment

  • React Native Navigation version: 6.9.1
  • React Native version: 0.62.2
  • Platform(s) (iOS, Android, or both?): iOS
  • Device info (Simulator/Device? OS version? Debug/Release?): Emulator 13.2.2 Debug
requires reproduction

Most helpful comment

@vishalenrique It'd be awesome if you could create a separate issue with a reproduction on Github so we could have a look at the bug 👍 .

@karlmarxlopez Glad you were able to resolve the updateProps issue. As your solution suggests Navigation.updateProps expects the componentId of the RNN screen you are wishing to update. So by providing a custom id when displaying the title component and use the same id you used in Navigation.updateProps, it successfully updates the props.

I'll see if I could improve the current documentation to better demonstrate the correct usage of the Navigation.updateProps API. Cheers!

All 5 comments

Hey @karlmarxlopez Can you reproduce the issue in the Playground app?

@guyca Hey, I'm facing the same issue wherein both the screens(Screen1 & Screen2) have a custom title component. When poping Screen 2 and trying to update the title's props from componentDidAppear method in Screen1, it has no effect on UI. Although the new title props are being passed to custom title component(checked by logging it) but UI title stays the one from Screen2. Any suggestion?

Hey @karlmarxlopez Can you reproduce the issue in the Playground app?

NVM @guyca , I've fixed my problem by providing an id to the title component.

options: {
    topBar: {
      title: {
        component: {
          id: 'MyCustomTitleComponent', // add this and use it on `updateProps` method
          name: "MyCustomTitleComponent",
          passProps: { count: 1 },
        },
      },
    },
  },
Navigation.updateProps('MyCustomTitleComponent', { count: 123 });

@vishalenrique I've noticed that too, sometimes it does not update the component. I ended up using redux to guarantee re-render when I change the pagination active index. It has an extra step on screen registration because you need to add a provider and it's overkill for my use case but, I have a deadline, I'll go back to updateProps if I have time to refactor.

@vishalenrique It'd be awesome if you could create a separate issue with a reproduction on Github so we could have a look at the bug 👍 .

@karlmarxlopez Glad you were able to resolve the updateProps issue. As your solution suggests Navigation.updateProps expects the componentId of the RNN screen you are wishing to update. So by providing a custom id when displaying the title component and use the same id you used in Navigation.updateProps, it successfully updates the props.

I'll see if I could improve the current documentation to better demonstrate the correct usage of the Navigation.updateProps API. Cheers!

Was this page helpful?
0 / 5 - 0 ratings