Passing Props from a Functional component to a class component

44 Views Asked by At

I am doing a React tutorial and author has a playground where everything works. But in my IDE when I try to pass props to a class component, the component does not recognize the props. I have been at it for a couple of hours now. Can someone point out what is wrong with my code and why it should be working at https://jscomplete.com/playground/rgs2.4

const testData = [
  {name: "Dan Abramov", avatar_url: "https://avatars0.githubusercontent.com/u/810438?v=4", company: "@facebook"},
  {name: "Sophie Alpert", avatar_url: "https://avatars2.githubusercontent.com/u/6820?v=4", company: "Humu"},
  {name: "Sebastian Markbåge", avatar_url: "https://avatars2.githubusercontent.com/u/63648?v=4", company: "Facebook"},
];

const root = ReactDOM.createRoot(
  document.getElementById('root') as HTMLElement
);


class App extends React.Component {
  render() {
    return (
      <div>
        <div className="header">{this.props.title}</div>
        <CardList />
      </div>
    );
  }
}

root.render(
  <App title="The GitHub Cards App" />
);


const CardList = () => (
      <div>
        {testData.map(profile => <Card {...profile}/>)}
      </div>
);


class Card extends React.Component {
  render() {
      const profile = this.props;
      return (
          <div className="github-profile">
             <img src={profile.avatar_url} alt="Cant show "/>
             <div className="info" style={{verticalAlign:'top'}}>
              <div className="name" style={{fontSize:'125%'}}>{profile.name}</div>
              <div className="company">{profile.company}</div>
             </div>
          </div>
      );
  }
}

For example in the line < App title="The GitHub Cards App" / > I get following error on "title" in the render, and the App component says prop.title does not exist

No overload matches this call.
  Overload 1 of 2, '(props: {} | Readonly<{}>): App', gave the following error.
    Type '{ title: string; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes<App> & Readonly<{}>'.
      Property 'title' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes<App> & Readonly<{}>'.
  Overload 2 of 2, '(props: {}, context: any): App', gave the following error.
    Type '{ title: string; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes<App> & Readonly<{}>'.
      Property 'title' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes<App> & Readonly<{}>'

Again in the Card component, profile properties, like avatar_url, name and company are not present, for example - Property 'name' does not exist on type 'Readonly<{}>

There are slight differences in my version and the one on https://jscomplete.com/playground/rgs2.4 This is due to React version, probably not causing this situation. If anyone has a clue looking at this, please help me get unstuck.

Thanks

1

There are 1 best solutions below

3
Chris Hamilton On BEST ANSWER

In Typescript, components are typed using Generics. The Component declaration is

Component<P = {}, S = {}, SS = any>

P: Props, default type = {}

S: State, default type = {}

SS: SnapShot, default type = any

In your case you are trying to type the props.

type AppProps = {
  title: string;
};
class App extends React.Component<AppProps> {
...

type CardProps = {
  avatar_url: string;
  name: string;
  company: string;
};
class Card extends React.Component<CardProps> {
...

With function components you can use FC<P = {}>, which just has the generic type for props

type AppProps = {
  title: string;
};
const App: React.FC<AppProps> = ({ title }) => {
...

type CardProps = {
  avatar_url: string;
  name: string;
  company: string;
};
const Card: React.FC<CardProps> = ({ avatar_url, name, company }) => {
...

If you don't want to use Typescript, since the code you provided doesn't actually use any, name your file with extension .jsx instead of .tsx.