Conor Watson
Conor Watson

Reputation: 617

Using Render Props in React Native

I am developing a React-Native component that is supposed to be used as a 'Select' picker, that displays a FlatList. I would like the renderItem function of the FlatList to be customizable, in essence I would like to pass a custom render function to the SelectPicker component which will be responsible for rendering the List items.

In the StandardPicker component I have a render function which looks like the following:

render() {
  const { range } = this.props;
  return (
    <View style={styles.modal}>
      <FlatList
        data={range}
        renderItem={this.renderListItem}
      />
    </View>
  );
}

and the renderListItem function looks like this

renderListItem({ item, index }) {
  const { onSelectItem, renderItem } = this.props;

  const renderedItem = renderItem ? (
    renderItem()
  ) : null

  return (
    <TouchableNative
      key={index}
      onPress={() => {
        onSelectItem(index);
      }}
    >
      {renderedItem}
    </TouchableNative>
  );
}

Now in a different component I am rendering the StandardPicker and passing a render function like so

renderCustomItem() {
  return (
    <View>
      <Text>Testing</Text>
      <Text>Test 2</Text>
    </View>
  );
}

<StandardPicker
  range={this.listItems}
  onSelectItem={item=>
    this.setState({ selectedItem: item})
  }
  renderItem={this.renderCustomItem}
/>

However I end up getting an error Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: undefined.

Is there something I am missing or can this not be done in React-Native?

Upvotes: 0

Views: 1938

Answers (1)

Michael Ostrovsky
Michael Ostrovsky

Reputation: 629

It feels you're complicating this more than you need to, you can absolutely pass a render function to a Component but it's much easier to just pass the body, now the error you're getting seems to be some kind of import/spelling error as one of the objects you're using is in-fact as the code says, undefined now I would need a better look at your code to find out exactly where it's happening but either way you can feel free to shorten your function like this:

renderListItem({ item, index }) {
  const { onSelectItem, renderItem } = this.props;

  return (
    <TouchableNative
      key={index}
      onPress={() => {
        onSelectItem(index);
      }}
    >
      {renderItem}
    </TouchableNative>
  );
}

As if it's undefined the JSX won't render anything there either way.

Upvotes: 1

Related Questions