I am trying to call a function inside child component through this.refs but i keep getting error that this function doesn't exist.
Uncaught TypeError: this.refs.todayKpi.loadTodaysKpi is not a function
Parent component:
class KpisHeader extends React.Component {
constructor() {
super();
this.onUpdate = this.onUpdate.bind(this);
}
render(){
return <div>
<DateRange ref="dateRange" onUpdate={this.onUpdate}/>
<TodayKpi ref="todayKpi" {...this.state}/>
</div>;
}
onUpdate(val){
this.setState({
startDate: val.startDate,
endDate: val.endDate
}, function(){
this.refs.todayKpi.loadTodaysKpi();
});
}
}
I want to get some data from DateRange component through function onUpdate, and then I want to trigger a function inside TodayKpi which fetches data from the server. For now it is just console.log("AAA");.
Child component:
class TodayKpi extends React.Component {
constructor() {
super();
this.loadTodaysKpi = this.loadTodaysKpi.bind(this);
}
render(){
console.log(this.props.startDate + " "+ this.props.endDate);
return <div className="today-kpi">
</div>;
}
loadTodaysKpi(){
console.log("AAAA");
}
}
How should I implement this?
To pass a function as props in React TypeScript: Define a type for the function property in the component's interface. Define the function in the parent component. Pass the function as a prop to the child component.
To call a parent component method from the child component, we need to pass the changeName() method as a prop to the child component and access it as a props data inside the child component.
For reasons I don’t yet grasp, React discourages calling child methods from the parent. However, they relent and give us an ‘escape hatch’ which allows just that. You were correct in thinking that ‘Refs’ were a part of that escape hatch. If, like me, you have read dozens of articles searching for this information, you will be well prepared to understand their description of the escape hatch
In your case, you may want to try something like this in your KpisHeader class.
Change this line
<TodayKpi ref="todayKpi" {...this.state}/>
to use a ref callback function something like this:
<TodayKpi ref={(todayKpiComponent) => this.todayKpiComponent = todayKpiComponent} {...this.state}/>
or, pre-ES6, this:
<TodayKpi
ref=
{
function (todayKpiComponent)
{
this.todayKpiComponent = todayKpiComponent
}
}
{...this.state}
/>
Then you will be able to access your todayKpi component methods from your KpisHeader class like this:
this.todayKpiComponent.someMethod();
Oddly, for me, inside the ref callback function, ‘this’ was the window rather than the parent component. So, I had to add
var self = this;
above the render method and use ‘self’ inside the ref callback function.
In my case I had an unknown number of dynamically generated children components, so I put each one into an array. I cleared the array in componentWillUpdate. It all seems to be working but I have an uneasy feeling especially given React’s distaste for calling children’s methods.
If you want the function/method to be called inside the child, you should pass it to the child from the parent to start with. The other thing that you need to change is onUpdate
to onChange
, assuming that you want to track every change to that field. The other alternative is to check when it is onSubmit
, but it sounds like you want to have it happen every time the field is updated.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With