Touchable child must either be native or forward native setNativeProps?

#1

I’m making themed ui components and it’s worked great until I got to icons. I am running into a weird error.


This works

import React from 'react';
import { Platform, TouchableHighlight } from 'react-native';
import { MaterialCommunityIcons as Icon } from '@expo/vector-icons';

const LeftDrawerMenuButton = ({ navigation }) => (
  <TouchableHighlight
    onPress={() => {
      navigation.navigate('DrawerOpen');
    }}
  >
    <Icon name="menu" size={24} style={{ padding: Platform.OS === 'ios' ? 10 : 16 }} />
  </TouchableHighlight>
);

export default LeftDrawerMenuButton;

This is broken

import React from 'react';
import { Platform, TouchableHighlight } from 'react-native';
import { MaterialCommunityIcons as Icon } from '@expo/vector-icons';

const LeftDrawerMenuButton = ({ navigation }) => (
  <TouchableHighlight
    onPress={() => {
      navigation.navigate('DrawerOpen');
    }}
  >
    <ThemedIcon />
  </TouchableHighlight>
);

const ThemedIcon = () => (
  <Icon name="menu" size={24} style={{ padding: Platform.OS === 'ios' ? 10 : 16 }} />
);

export default LeftDrawerMenuButton;

The phone says this:

And the console says this:

Warning: Stateless function components cannot be given refs (See ref “childRef” in ThemedIcon created by TouchableHighlight). Attempts to access this ref will fail.


My Google-foo is weak on this one. Thanks for any help being pointed in the right direction!

0 Likes

#2

It looks like this is maybe a similar issue with a decent length response about how to troubleshoot/resolve? https://github.com/facebook/react-native/issues/1040

1 Like

#3

In addition to what @dikaiosune mentioned, some valuable links:

1 Like

#4

Awesome. Super helpful info. Thanks guys!

So I either

  • Correctly call ensureComponentIsNative and implement setNativeProps
    or
  • Wrap my custom component in a native component View.

Going with the latter and… it works!

import React from 'react';
import { Platform, TouchableHighlight, View } from 'react-native';
import { MaterialCommunityIcons as Icon } from '@expo/vector-icons';

const LeftDrawerMenuButton = ({ navigation }) => (
  <TouchableHighlight
    onPress={() => {
      navigation.navigate('DrawerOpen');
    }}
  >

    <View><ThemedIcon /></View>

  </TouchableHighlight>
);

const ThemedIcon = () => (
  <Icon name="menu" size={24} style={{ padding: Platform.OS === 'ios' ? 10 : 16 }} />
);

Now on to some theming! :smiley:

1 Like