Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Call child function from parent component in React Native

Tags:

react-native

I'm developing my first React Native app. What I'm trying to achieve is to execute a child function from the parent component, this is the situation:

Child

export default class Child extends Component {
  ...
  myfunct: function() {
    console.log('Managed!');
  }
  ...
  render(){
    return(
      <Listview
      ...
      />
    );
  }
}

Parent

export default class Parent extends Component {
  ...
  execChildFunct: function() {
    ...
    //launch child function "myfunct"
    ...
    //do other stuff
  }

  render(){
    return(
      <View>
        <Button onPress={this.execChildFunct} />
        <Child {...this.props} />
      </View>);
  }
}

In this example, I would like to log 'Managed!' when I press the button in the parent class. How is it feasible?

like image 578
Pottercomuneo Avatar asked Oct 28 '16 14:10

Pottercomuneo


People also ask

How do you call a function in parent component react?

To do this you pass a callback as a property down to the child from the parent. For example: var Parent = React. createClass({ getInitialState: function() { return { value: 'foo' } }, changeHandler: function(value) { this.

How do you access child component in parent component react?

In React we can access the child's state using Refs. we will assign a Refs for the child component in the parent component. then using Refs we can access the child's state. Creating Refs Refs are created using React.


5 Answers

Nader Dabit's answer is outdated, since using String literals in ref attributes has been deprecated. This is how we would do it as of September 2017:

<Child ref={child => {this.child = child}} {...this.props} />
<Button onPress={this.child.myfunc} />

Same functionality, but instead of using a String to reference the component, we store it in a global variable instead.

like image 62
Incinerator Avatar answered Oct 24 '22 01:10

Incinerator


You can add a ref to the child component:

<Child ref='child' {...this.props} />

Then call the method on the child like this:

<Button onPress={this.refs.child.myfunc} />
like image 30
Nader Dabit Avatar answered Oct 24 '22 00:10

Nader Dabit


Here's how you can do this with functional components:

Parent

  1. Use useRef() to give the child component a reference in the parent:
const childRef = useRef()
// ...
return (
   <ChildComponent ref={childRef} />
)
...

Child

  1. Pass ref as one of the constructor parameters:
const ChildComponent = (props, ref) => {
  // ...
}
  1. Import useImperativeHandle and forwardRef methods from the 'react' library:
import React, { useImperativeHandle, forwardRef } from 'react'
  1. Use useImperativeHandle to bind functions to the ref object, which will make these functions accessible to the parent

These methods won't be internally available, so you may want to use them to call internal methods.

const ChildComponent = (props, ref) => {
  //...
  useImperativeHandle(ref, () => ({
    // each key is connected to `ref` as a method name
    // they can execute code directly, or call a local method
    method1: () => { localMethod1() },
    method2: () => { console.log("Remote method 2 executed") }
  }))
  //...
  
  // These are local methods, they are not seen by `ref`,
  const localMethod1 = () => {
    console.log("Method 1 executed")
  }
  // ..
}
  1. Export the child component using forwardRef:
const ChildComponent = (props, ref) => {
  // ...
}
export default forwardRef(ChildComponent)

Putting it all together

Child Component

import React, { useImperativeHandle, forwardRef } from 'react';
import { View } from 'react-native'


const ChildComponent = (props, ref) => {
  useImperativeHandle(ref, () => ({
    // methods connected to `ref`
    sayHi: () => { sayHi() }
  }))
  // internal method
  const sayHi = () => {
    console.log("Hello")
  }
  return (
    <View />
  );
}

export default forwardRef(ChildComponent)

Parent Component

import React, { useRef } from 'react';
import { Button, View } from 'react-native';
import ChildComponent from './components/ChildComponent';

const App = () => {
  const childRef = useRef()
  return (
    <View>
      <ChildComponent ref={childRef} />
      <Button
        onPress={() => {
          childRef.current.sayHi()
        }}
        title="Execute Child Method"
      />
    </View>
  )
}

export default App

There is an interactive demo of this on Expo Snacks: https://snack.expo.dev/@backupbrain/calling-functions-from-other-components

This explanation is modified from this TutorialsPoint article

like image 24
Adonis Gaitatzis Avatar answered Oct 23 '22 23:10

Adonis Gaitatzis


it is in react. i hope it may help you.

class Child extends React.Component {
  componentDidMount() {
    this.props.onRef(this)
  }
  componentWillUnmount() {
    this.props.onRef(null)
  }
  method() {
    console.log('do stuff')
  }
  render() {
    return <h1>Hello World!</h1>
  }
}

class EnhancedChild extends React.Component {
        render() {
        return <Child {...this.props} />
      }
    }

class Parent extends React.Component {
  onClick = () => {
    this.child.method() // do stuff
  };
  render() {
    return (
      <div>
        <EnhancedChild onRef={ref => (this.child = ref)} />
        <button onClick={this.onClick}>Child.method()</button>
      </div>
    );
  }
}

ReactDOM.render(<Parent />, document.getElementById('root'))

Original Solution:

https://jsfiddle.net/frenzzy/z9c46qtv/

https://github.com/kriasoft/react-starter-kit/issues/909

like image 8
Ashok R Avatar answered Oct 23 '22 23:10

Ashok R


Simple and easy way to Parent --> Child function call

/* Parent.js */
import React, { Component } from "react";
import { TouchableOpacity, Text } from "react-native";
import Child from "./Child";

class Parent extends React.Component {
  onChildClick = () => {
    this.child.childFunction(); // do stuff
  };
  render() {
    return (
      <div>
        <Child onRef={(ref) => (this.child = ref)} />
        <TouchableOpacity onClick={this.onChildClick}>
          <Text>Child</Text>
        </TouchableOpacity>
      </div>
    );
  }
}

/* Child.js */
import React, { Component } from "react";

class Child extends React.Component {
  componentDidMount() {
    this.props.onRef(this);
  }
  componentWillUnmount() {
    this.props.onRef(undefined);
  }
  childFunction() {
    // do stuff
    alert("childFunction called");
  }
  render() {
    return <View>Hello World!</View>;
  }
}

Original Solution: https://github.com/kriasoft/react-starter-kit/issues/909

like image 7
Himanshu padia Avatar answered Oct 24 '22 01:10

Himanshu padia