Search code examples
javascriptreact-nativecallbackreact-native-flatlistreact-native-component

How to get callback from child component to parent component in React Native


I have been working on react-native to get the callback from child to parent. Below is the code snippet of my implementation:

MainView.js

import React, { Component } from 'react';
import {
    StyleSheet,
    View,
    Text,
    Image,
    TouchableHighlight,
    FlatList,
    Dimensions,
} from 'react-native';
import ListCell from './ListCell';
import {displayAlert} from './CustomAlert';
type Props =  {
};

let winSize = Dimensions.get('window');
export default class MainView extends Component<Props> {

_keyExtractor = (item, index) => { return(index.toString());};

  _renderItem = ({item, index}) => {
    return (<ListCell
    item={item}
    index={index}
    onPressItem={this._onPressItem}
    />);
  };
  _onPressItem = (item,index) => {
    console.log("Pressed row : "+index);
    displayAlert();
    // this.props.navigation.navigate('Detail',{item: item});
  };
    render() {
        return(
            <FlatList
        style={styles.flatListStyle}
        data={this.props.listing}
        keyExtractor={this._keyExtractor}
        renderItem={this._renderItem}
      />
        );
    }
}

The list Cell Component for FlatList is :

ListCell.js

import React, {PureComponent} from 'react';
import {
    StyleSheet,
    TouchableHighlight,
    View,
    Image,
    Text,
} from 'react-native'


export default class ListCell extends PureComponent {
  _onPress() {
    this.props._onPressItem(this.props.item,this.props.index);
  }
  render() {
    const item = this.props.item;
    const price = item.price_formatted.split(' ')[0];
    return (
      <TouchableHighlight
      style={styles.listCellContainer}
      onPress={this._onPress}
      underlayColor='#dddddd'>
        <View >
          <View style={styles.rowContainer}>
            <Image style={styles.thumb} source={{uri:item.img_url}}/>
            <View style={styles.textContainer}>
              <Text style={styles.price}>{price}</Text>
              <Text style={styles.title}>{item.title}</Text>
            </View>
          </View>
        </View>
      </TouchableHighlight>
    );

  }
}

this code will work fine when declared in single file, but when seperated in two different file it gives an error stating this.props._onPressItem is undefined when tap on cell.

I have followed the following https://medium.com/@ruthmpardee/passing-data-between-react-components-103ad82ebd17 approach but didn't succeed on that either Any suggestions would be helpful.


Solution

  • Got a quick look on your code. This is what I found.

    export default class ListCell extends PureComponent {
      _onPress() {
        this.props.onPressItem(this.props.item,this.props.index); //Change: passing prop onPressItem and calling _onPressItem
      }
      render() {
        const item = this.props.item;
        const price = item.price_formatted.split(' ')[0];
        return (
          <TouchableHighlight
          style={styles.listCellContainer}
          onPress={this._onPress} //Try: Also bind the event () => this._onPress()
          underlayColor='#dddddd'>
            <View >
              <View style={styles.rowContainer}>
                <Image style={styles.thumb} source={{uri:item.img_url}}/>
                <View style={styles.textContainer}>
                  <Text style={styles.price}>{price}</Text>
                  <Text style={styles.title}>{item.title}</Text>
                </View>
              </View>
            </View>
          </TouchableHighlight>
        );
    
      }
    }