gkeenley
gkeenley

Reputation: 7358

Can't call child component method from parent component in React Native

I have a React Native component <Parent> that contains a component <Child>, and I want to be able to call one of Child's methods in Parent. After reading a bunch of other posts, this is what I have:

Child.js

export default class Child extends Component {
  method1() {
    console.log("success");
  }
  render() {
    return(
      <View/>
    )
  }
}

Parent

export default class Parent extends Component {
  render() {
    return(
      <View>
        <TouchableOpacity
          onPress={() => this.child.method1()}
        />
        <Child
          onRef={ref => (this.child = ref)}
        />
      </View>
    )
  }
}

I'm getting the error "_this2.child.method1 is not a function."

Other things I've tried are using refInput instead of onRef, and doing ref => {this.child = ref} instead of ref => (this.child = ref).

Any ideas?

Thanks!

Upvotes: 5

Views: 3555

Answers (4)

Shubham Khatri
Shubham Khatri

Reputation: 281656

You can create a ref using React.createRef in the constructor and assign it to the Child component instance using ref prop

Post that you can access the child using this.child.current

Sample code:

class Child extends React.Component {
  myMethod() {
    console.log("myMethod called");
  }

  render() {
    return <Text>This is child</Text>;
  }
}

class App extends Component {
  constructor() {
    super();
    this.child = React.createRef();
  }
  render() {
    return (
      <View style={styles.app}>
        <View style={styles.header}>
          <Image
            accessibilityLabel="React logo"
            source={{ uri: logoUri }}
            resizeMode="contain"
            style={styles.logo}
          />
          <Text style={styles.title}>React Native for Web</Text>
        </View>
        <Child ref={this.child} />
        <Button
          onPress={() => {
            this.child.current.myMethod();
          }}
          title="Example button(Click to trigger Child)"
        />
      </View>
    );
  }
}

Working demo

IF your child component is connected with connect from redux, you can still access the childRef by setting the withRef option to true in connect

connect(mapStateToProps, mapDispatchToProps, null, { withRef: true })(Child);

If you are using v6 or above of redux, set the forwardRef property instead of withRef

connect(mapStateToProps, mapDispatchToProps, null, { forwardRef: true })(Child);

Once you do that in the parent you will be able to access the cchild ref with

this.child.current.getWrappedInstance()

Upvotes: 6

Sagar Chavada
Sagar Chavada

Reputation: 5269

Finally found the problem.

@Shubham khatri's answer will definitely work, It will only not work with redux.

if your child class is wrap with connect

export default connect(mapStateToProps)(Athletes);

It will not work in this case so make sure you use it normal way, if you want to call child method from parent class.

Upvotes: 0

Paras Korat
Paras Korat

Reputation: 2065

Use ref to call child method

export default class Parent extends Component {
  render() {
    return(
      <View>
        <TouchableOpacity
          onPress={() => this.refs.child.method1()}//<---------
        />
        <Child
          ref="child"//<-------
        />
      </View>
    )
  }
}

Upvotes: 0

Matt Way
Matt Way

Reputation: 33151

One way you can do this is by passing a function down to the child, that the child can pass a function to. For example:

<TouchableOpacity
  onPress={() => this.childFunc()}
/>
<Child addMethod={func => this.childFunc = func}/>

Then just call the props.addFunc(this.method1) from inside the child. Just make sure your this is the one you want.

More importantly though, you should ask yourself why you need to do this in the first place.

Upvotes: 2

Related Questions