Reputation: 331
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
Upvotes: 1
Views: 5675
Reputation: 1988
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>
)
}
}
Upvotes: 2
Reputation: 102
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
};
};
Upvotes: 0
Reputation: 16309
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}
/>
}>
...
Upvotes: 6