38

I have a parent and child compoents and I want to call a parent method in the child component like this:

import Parent from './parent.js';
class Child extends React.Component {
    constructor(props) {
        super(props);
        };

    click() {
        Parent.someMethod();
    }

    render() {
          <div>Hello Child onClick={this.click}</>
    }
}

class Parent extends React.Component {
    constructor(props) {
        super(props);
        };

    someMethod() {
        console.log('bar');
    }

    render() {
          <div>Hello Parent</>
    }
}

This returns an error message:

Uncaught TypeError: _Parent2.default.someMethod is not a function

How can this parent method be called in the child component?

isherwood
  • 58,414
  • 16
  • 114
  • 157
user94628
  • 3,641
  • 17
  • 51
  • 88
  • 1
    You're calling it as if it's a static property. It's not it's a method. My suggestion would be not to create this coupling and to pass it in as a prop instead. – Benjamin Gruenbaum Oct 18 '16 at 13:34

2 Answers2

74

Try this. Passing the function down as props to the child component.

import Parent from './parent.js';
class Child extends React.Component {
    constructor(props) {
        super(props);
        };

    click = () => {
        this.props.parentMethod();
    }

    render() {
          <div onClick={this.click}>Hello Child</div>
    }
}

class Parent extends React.Component {
    constructor(props) {
        super(props);
        };

    someMethod() {
        console.log('bar');
    }

    render() {
          <Child parentMethod={this.someMethod}>Hello Parent, {this.props.children}</Child>
    }
}
Martin Dawson
  • 7,455
  • 6
  • 49
  • 92
  • Running this gives an error `warning.js:36 Warning: Unknown prop `parentMethod`on
    tag. Remove this prop from the element`
    – user94628 Oct 18 '16 at 13:48
  • @user94628 It's because it needs to be the `Child` component and not `div`. Updated. – Martin Dawson Oct 18 '16 at 13:49
  • I get this error: `TypeError: Cannot read property 'props' of undefined` in the Child component. – Si8 Jul 19 '19 at 01:04
  • 1
    that's because `this` isn't correctly bound to your class for some reason. try using `.bind` in the constructor. Not exactly sure why because it should work. – Martin Dawson Jul 20 '19 at 12:29
  • I asked a question, on SO about something like this, example I am needing to call `this.props.parentMethod();` OUTSIDE of the child component class Any idea @MartinDawson –  Dec 03 '19 at 22:21
  • @MartinDawson my question https://stackoverflow.com/questions/59166100/call-react-parent-component-function-from-outside-of-the-child-component-class –  Dec 03 '19 at 22:22
  • TypeError: this.props.parentMethod is not a function . Someone please help :). Thanks – Ayushman Kumar May 28 '20 at 11:40
  • @AyushmanKumar you need to pass the parentMethod down from the parent to the child as props – Martin Dawson May 28 '20 at 18:44
  • I gave a strong thumbs up to this answer because it is so simple and clear. A couple of observations from my experience: -it is probably not good to put in the import Parent statement, because it creates the reverse of the dependency you want. -My parent method calls other parent methods and I needed to add this line to the constructor of the parent: `this.someMethod=this.someMethod.bind(this);` The line above ensures that the method in question is using the parent context when calling this.anotherParentMethod within it. There may be other ways to accomplish the same thing – EGP Mar 26 '23 at 19:24
-1

You can try doing something like calling the function of parent by passing the state of your parent to the child and then call using the props in child class.

class FlatListItem extends Component{
constructor(props){
    super(props)

}
render(){

    return(
             <TouchableOpacity style={styles.button} 
                                    onPress= 
                               {(item)=>this.props.parentFlatlist.delete(item)}></TouchableOpacity>
        </Swipeout>
    )
}}

And now consider you have a parent class RandomList:

class RandomList extends Component{
static navigationOptions = ({navigation}) =>{
    return{
        headerTitle: 'Random List'
    }
};

state = {
    lists : [],
    refreshing : false
}

constructor(props){
    super(props)

}
delete= (item) =>{
//delete your item
      console.log(item)
}
    render(){
        return(
            <BackgroundImageComponent>
                            <FlatList
                                keyExtractor={item => item}
                                data = {this.state.lists}
                                renderItem = {({item,index}) => (
                               <FlatListItem onPress={()=>this.seeTheList(item)} item1={item} parentFlatList={this} index={index}>

                               </FlatListItem>
                            )}
                            />
                        </ScrollView>
        </BackgroundImageComponent>
    )
}}export default RandomList

See here, I am passing parentFlatlist={this} and then would be using the same instance later in the child class. The main idea is to focus upon the way I am able to render the delete function and not to focus upon the code. Forgive me if the code is misplaced or broken.

Siddharth Choudhary
  • 1,069
  • 1
  • 15
  • 20
  • 2
    Do not do this. There's no reason why the child needs access to the entire class, pass what you need instead so it's not ambiguous. Devs can also end up doing something stupid like setting the state in the child component if you pass the entire class down. – Martin Dawson Jul 20 '19 at 12:33
  • Yeah makes perfect sense! Thanks for sharing – Siddharth Choudhary Jul 20 '19 at 13:51