Source:  Twitter logo

As the title says, I am trying to call a method (componentDidMount) placed in a parent component from a child component - I have the following components structure in my app:

export default class Today extends Component {
    constructor(props) {
        super(props);
        this.state = {
            stats: [],
            loading: true
        };
    }

    componentDidMount() {
        axios.get(api_url)
            .then((res) => {
                console.log('res.data');   
                this.setState({ 
                    stats: res.data,
                    loading: false
                });
            })
    }

    render() {
        return (
            <Stats loading={this.state.loading} stats={this.state.stats} />
        );
    }
}

and

export default class Stats extends Component {

    constructor(props) {
        super(props);

    }

    onRefresh() {
        alert('X');
        // here I need to refresh the data in 'this.props.stats'
        // and re-display it (fresh data)
    }

    render() {
        const {loading, stats} = this.props;

        if (loading) {
            return (
               <Text>Loading...</Text>
            );
        } else {
            return (
                <Container>
                    <Content refreshControl={
                        <RefreshControl 
                            onRefresh={this.onRefresh.bind(this)}
                        />
                    }>
                    ...

But how do I re-call the code in Today -> componentDidMount from the Stats component?

Thank you in advance

Your Stats component needs to take an additional prop onRefresh that it passes to the RefreshControl component. The parent can then provide a handler via that prop that invokes the axios request:

class Today extends Component {
    // ...

    componentDidMount() {
        this.fetchData();
    }

    fetchData = () => {
        axios.get(api_url)
            .then((res) => {
                console.log('res.data');   
                this.setState({ 
                    stats: res.data,
                    loading: false
                });
            })
    }

    // handle a refresh by re-fetching
    handleRefresh = () => this.fetchData();

    render() {
        return (
            <Stats 
                loading={this.state.loading} 
                stats={this.state.stats} 
                onRefresh={this.handleRefresh}
            />
        );
    }
}

and

class Stats extends Component {
    render() {
        const {loading, stats, onRefresh} = this.props;

        if (loading) {
            return (
               <Text>Loading...</Text>
            );
        } else {
            return (
                <Container>
                    <Content refreshControl={
                        <RefreshControl 
                            onRefresh={onRefresh}
                        />
                    }>
                    ...
6 users liked answer #0dislike answer #06
trixn profile pic
trixn

This is how you call a parent method from inside the child component

Parent.js

import React from 'react';
import Child from './Child';

export default class Parent extends React.Component{
    parentMethod(data){
        console.log('parent method called', data)
    }
    render(){
        return (
            <div>
                <Child parentMethod={(data) => this.parentMethod(data)} />
            </div>
        )
    }
}

Child.js

export default class Child extends React.Component{
    render(){
        return (
            <div>
                <div onClick={() => this.props.parentMethod('Hello from child')} >Call Parent</div>
            </div>
        )
    }
}
2 users liked answer #1dislike answer #12
Singh profile pic
Singh

Well I think you can get a better structure for your parent and child components. I recommend read about Presentational Components vs Container Components

Presentational components

import React, {Component} from 'react';
import {View} from 'react-native';
import styles from './Header.component.style';

class Header extends Component {
  render () {
    const {title, subtitle} = this.props;
    return (
      <View style={styles.container}>
        <View style={styles.titleHeading}>{title}</View>
        <View style={styles.subtitle}>{subtitle}</View>
      </View>
    );
  }
}
export default Header;

Container components

import React, {Component} from 'react';
import Header from '../component/Header.component';

export default class Home extends Component {
   calculateSomething = () => {
     ...some calculation / api calls....
   }
   render () {
     const {title, subtitle, goToLogin} = this.props;
     return (
       <Header title={title} subtitle={subtitle} goToLogin={goToLogin} calculateSomething={this.calculateSomething}/>
     );
   }
 }
 const mapStateToProps = (state)=>{
   return {
     title: state.title,
     subtitle: state.subtitle
   };
 };
0 users liked answer #2dislike answer #20
Armando Mendivil profile pic
Armando Mendivil

Copyright © 2022 QueryThreads

All content on Query Threads is licensed under the Creative Commons Attribution-ShareAlike 3.0 license (CC BY-SA 3.0).