How to call React/Typescript child component function from parent component?

Viewed 1570

I am trying to use child component function "changeName" in a parent component. Getting the error Property 'superheroElement' does not exist on type 'App'. What could be the best way to solve this? The child component and parent component are as follows

import React,{Component} from 'react'; class Superhero extends React.Component { state = { name: "Batman" }; changeName = () => { this.setState({ name: "Bruce Wayne" }); }; render(){ return <div>{this.state.name}</div>; } } export default Superhero; import React, { Component, RefObject } from 'react'; import Superhero from './child' class App extends React.Component<any , any> { constructor(props:any) { super(props); this.superheroElement = React.createRef(); } handleClick = () => { this.superheroElement.current.changeName(); }; render() {return <div><Superhero ref={this.superheroElement}/> <button onClick={this.handleClick}>real name</button></div> } } export default App;
1 Answers

First of all, I don't think this is the best practice for React app as this opposes React's unidirectional data flow. So, this ref idea should only be the last resort.

For your problem, the easiest way to prevent the error is set the superheroElement to any.

import React from 'react';
import Superhero from './child'
class App extends React.Component<any, any> {

  superheroElement: any;

  constructor(props: any) {
    super(props);
    this.superheroElement = React.createRef();
  }
  handleClick = () => {
    this.superheroElement.current.changeName();
  };
  render() {return 
           <div><Superhero ref={this.superheroElement}/>
          <button onClick={this.handleClick}>real name</button></div>
  }
}
export default App;  

this way, the error will disappear. But, if you want to keep the typescript functionality, what you can do is give type to the RefObject.

import React, { RefObject } from 'react';
import Superhero from './child';
class App extends React.Component<any, any> {
  superheroElement: RefObject<Superhero>;

  constructor (props: any) {
    super(props);
    this.superheroElement = React.createRef();
  }

  handleClick = () => {
    if (this.superheroElement.current)
      this.superheroElement.current.changeName();
  };

  render () {
    return (
      <div>
        <Superhero ref={this.superheroElement} />
        <button onClick={this.handleClick}>real name</button>
      </div>
    );
  }
}
export default App;

Note: you can give the type of the child to createRef.

this.superheroElement = React.createRef<Superhero>();
Related