Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Call parent function from child component in React-Native ListView row

I have seen a few examples of this question but was unable to get any to work, or completely understand how it all fits together. I have a component called ParentListView and another called ChildCell (a row within the listView) I want the onPress from the ChildCell to call a function in ParentListView.

class ChildCell extends Component {

  pressHandler() {
    this.props.onDonePress;
  }

  render() {
    return (
        <TouchableHighlight onPress={() => this.pressHandler()} >
          <Text>Child Cell Button</Text>
        </TouchableHighlight>
    );
  }

}

and in ParentListView:

class ParentListView extends Component {  

//...

  render() {

    return (
      <ListView
        dataSource={this.state.dataSource}
        style={styles.listView}
        renderRow={this.renderCell}
        renderSectionHeader={this.renderSectionHeader}
        />
    );
  }

  renderCell() {
    return (
      <ChildCell onDonePress={() => this.onDonePressList()} />
    )
  }

  onDonePressList() {
    console.log('Done pressed in list view')
  }

}

I think that is all the pertinent code. I can get the press to register wishing the ChildCell, but cannot get the method to fire in ParentListView. What am I missing?

Thanks in advance!

UPDATE 1:

in ParentListView if I change the props passed in to this:

<ChildCell onDonePress={this.onDonePressList.bind(this)} />

I get the Unhandled JS Exception: null is not an object (evaluating 'this.onDonePressList') error at compile time when rendering the cell.

If I put the console.log directly in like this:

<ChildCell onDonePress={() => console.log('Done pressed in list view')} />

it logs the message fine.

If I leave it like I had originally:

<ChildCell onDonePress={() => this.onDonePressList()} />

It crashes on buttonPress with the Unhandled JS Exception: null is not an object (evaluating '_this2.onDonePressList')

UPDATE 2:

OK, I have tried binding the method in the constructor like so:

class ParentListView extends Component {
  constructor(props) {
    super(props);
    this.onDonePressList = this.onDonePressList.bind(this);
    this.state = {...};
}

but it gives me this error: null is not an object (evaluating 'this.onDonePressList') and will not run.

UPDATE 3: Here is a link to a react native playground

like image 380
Michael Campsall Avatar asked May 11 '16 21:05

Michael Campsall


People also ask

How do you call parent function from child component in react native?

To call a parent's function from a child component, pass the function reference to the child component as a prop. Then you can call that parent's function from the child component like props. parentMethodName().

How do you call parent method from child component?

Call Parent Component method from Child Component For Calling Parent Component method from Child Component, I had created a method getParentMethod and in this method, I had set input property in HTML file of parent component. Then shown as below code inside the child component I am able to access parent method.

How do you get parent data from a child in react?

React. js allows us to use props (short form of property) to pass data from parent component to child component. We have to set props value inside the child component, while we embed it to the parent component.

How can child components communicate with the parent component?

In the parent component, create a callback function. This callback function will retrieve the data from the child component. Pass the callback function to the child as a props from the parent component. The child component calls the parent callback function using props and passes the data to the parent component.


1 Answers

Try calling onDonePress in pressHandler like this:

pressHandler() {
  this.props.onDonePress()
}

Also, bind this to your renderRow and renderSectionHeader:

<ListView
    dataSource={this.state.dataSource}
    style={styles.listView}
    renderRow={this.renderCell.bind(this)}
    renderSectionHeader={this.renderSectionHeader.bind(this)}
    />

I've set up an example here using the above function.

https://rnplay.org/apps/DcdAuw

like image 134
Nader Dabit Avatar answered Sep 30 '22 10:09

Nader Dabit