Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React Native pass function to child component as prop

I'm new to React Native (and React), and I'm trying to pass a function as a prop to a component.

My goal is to create a component where its onPress functionality can be set by the instantiator of the component, so that it is more reusable.

Here is my code so far.

App.js

import React, { Component } from 'react';
import { View } from 'react-native';
import TouchableButton from './components/touchable-button';

export default class App extends Component<Props> {
  constructor () {
    super();
  }

  handlePress () {
    // this should be called when my custom component is clicked
  }

  render () {
    return (
      <View>
        <TouchableButton handlePress={this.handlePress.bind(this)}/>
      </View>
    );
  }
}

TouchableButton.js

import React, { Component } from 'react';
import { TouchableHighlight } from 'react-native';
import AppButton from "./app-button";

export default class TouchableButton extends Component {
  handlePress;

  constructor(props){
    super(props);
  }

  render () {
    return (
      <TouchableHighlight onPress={
        this.props.handlePress
      }>
        <AppButton/>
      </TouchableHighlight>
    );
  }
}

I am passing the handlePress function as the prop handlePress. I would expect the TouchableButton's props to contain that function, however it isn't there.

like image 974
Jerred Shepherd Avatar asked Mar 29 '18 03:03

Jerred Shepherd


People also ask

Can you pass a component as a prop React native?

You can pass a component as props in React by using the built-in children prop. All elements you pass between the opening and closing tags of a component get assigned to the children prop. Copied!


3 Answers

Solution

Use arrow function for no care about binding this.

And I recommend to check null before calling the props method.

App.js

export default class App extends Component<Props> {
  constructor () {
    super();
  }

  handlePress = () => {
    // Do what you want. 
  }

  render () {
    return (
      <View>
        <TouchableButton onPress={this.handlePress}/>
      </View>
    );
  }
}

TouchableButton.js

import React, { Component } from 'react';
import { TouchableHighlight } from 'react-native';
import AppButton from "./app-button";

export default class TouchableButton extends Component {
  constructor(props){
    super(props);
  }
  
  handlePress = () => {
    // Need to check to prevent null exception. 
    this.props.onPress?.(); // Same as this.props.onPress && this.props.onPress();
  }

  render () {
    return (
      <TouchableHighlight onPress={this.handlePress}>
        <AppButton/>
      </TouchableHighlight>
    );
  }
}
like image 124
Jeff Gu Kang Avatar answered Oct 19 '22 08:10

Jeff Gu Kang


When writing handlePress={this.handlePress.bind(this)} you passing a statement execution ( which when and if executed returns a function). What is expected is to pass the function itself either with handlePress={this.handlePress} (and do the binding in the constructor) or handlePress={() => this.handlePress()} which passes an anonymous function which when executed will execute handlePress in this class context.

like image 28
Moti Korets Avatar answered Oct 19 '22 09:10

Moti Korets


// Parent

handleClick( name ){
   alert(name);
}

<Child func={this.handleClick.bind(this)} />

// Children

let { func } = this.props;

func( 'VARIABLE' );
like image 4
Naycho334 Avatar answered Oct 19 '22 10:10

Naycho334