Ad

How To Add NavigationOptions To A Memoized React Functional Component?

I'm using flow types and have a memo wrapped functional component, however when trying to assign navigationOptions for react-navigation, flow is just going haywire:

On my component

const navigationOptions = ({navigation}) => ({}) // more stuff

const Foo = memo((props: IProps) => {
...
})

/*
Here it breaks down
Cannot assign `navigationOptions` to `Foo['navigation...']` because property `navigationOptions` is missing in  `React.AbstractComponentStatics`
*/
Foo.navigationOptions = navigationOptions
export default Foo

Even if I type cast it to any, and then try to use it on my router:

/*
Cannot call `createStackNavigator` with object literal bound to `routeConfigMap` because in property `Foo.screen`: Either property `navigationOptions` is missing in  AbstractComponent [1] but exists in  `withOptionalNavigationOptions` [2]. Or property `router` is missing in  AbstractComponent [1] but exists in  `withRouter` [3].Flow(InferError)
*/
const FooStack = createStackNavigator({
  Foo: { screen: FooScreen }
}, stackNavOptions)

How am I supposed to properly apply types here?

Ad

Answer

This is an expected behaviour. If you actually check React$AbstractComponentStatics you'll see that there are very few allowed properties, such as displayName which is valid. They've even removed propTypes which even though it's valid it's not encouraged which is why it has been removed.

To get around this you can use a suppression comments to mark it as a false positive,

// $FlowExpectedError navigationOptions
Foo.navigationOptions = navigationOptions

Flow supports $FlowFixMe and as of version 0.125.0, $FlowIssue and $FlowExpectedError by default to suppress errors.

Ad
source: stackoverflow.com
Ad