0

I'm building my first Ionic React app and created a simple custom component that returns content based on two optional input values.

When I had a simple if/else if/else conditional, the component rendered fine, but adding an extra 'else if' prevents it from compiling and I've not been able to establish why.

Here's the working component:

import React from 'react';
import './CardContainer.css';

interface ContainerProps {
    position?: string;
    content?: string;
}

const CardContainer: React.FC<ContainerProps> = ({ position = "right", content = "n/a"}) => {
    let cardOutput;
    if ( position.trim().toLowerCase() === "right" ) {
        cardOutput = <><div className="ion-float-right">{content}</div><div className="clear-right"></div></>;
    } else if ( position.trim().toLowerCase() === "left" ) {
        cardOutput = <div className="ion-float-left">{content}</div>;
    } else {
        cardOutput = <div className="ion-float-left">{content}</div>;
    }
    return (
        cardOutput
    )
};


export default CardContainer;

And here is the code that won't compile:

import React from 'react';
import './CardContainer.css';

interface ContainerProps {
    position?: string;
    content?: string;
}

const CardContainer: React.FC<ContainerProps> = ({ position = "right", content = "n/a"}) => {
    let cardOutput;
    if ( position.trim().toLowerCase() === "right" ) {
        cardOutput = <><div className="ion-float-right">{content}</div><div className="clear-right"></div></>;
    } else if ( position.trim().toLowerCase() === "left" ) {
        cardOutput = <div className="ion-float-left">{content}</div>;
    } else if ( position.trim().toLowerCase() === "empty" ) {
        cardOutput = <div className="ion-padding-top">{content}</div>;
    }
    return (
        cardOutput
    )
};

export default CardContainer;

The only significant difference is that I've replaced the 'else' condition with an 'else if'. I've tried adding in an 'else' condition just to eliminate possible cause and this as expected doesn't fix the issue.

When I try and run the app on my dev system I get this output:

Type '({ position, content }: PropsWithChildren) => Element | undefined' is not assignable to type 'FC'. Type 'Element | undefined' is not assignable to type 'ReactElement<any, any> | null'. Type 'undefined' is not assignable to type 'ReactElement<any, any> | null'.ts(2322)

To my inexperienced eye this doesn't give me much indication of what the issue is beyond it relating to TypeScript.

halfer
  • 19,824
  • 17
  • 99
  • 186
Phill Healey
  • 3,084
  • 2
  • 33
  • 67

2 Answers2

2

This is because your data may lie in the if conditions and thus the variable declared cardoutput is still undefined.

let cardOutput;//undefined

So try to use an else condition so that the cardoutput wont be undefined

Naveenkumar M
  • 616
  • 3
  • 17
  • I'm not sure what you mean. The output is essentially the same in all cases and it works with just 2 if/else conditions. Could you give an example to make it easier to understand what you mean in this case? Thanks. – Phill Healey Oct 25 '21 at 15:30
  • Ok, so i see that that new condition doesn't output any of the incoming props. Is this what you mean? If so, how do I best define 'cardOutput' ? I've tried `let cardOutput:string;` and `let cardOutput = ""` but these don't have the desired effect. I've fixed it by using `let cardOutput = "<>>;"` Is there a better way? – Phill Healey Oct 25 '21 at 15:33
  • You can have a default value or an else value to solve the error – Naveenkumar M Oct 25 '21 at 15:38
  • On some conditions your if conditions may fail at the time the variable should have a default value or an else value otherwise it would be undefined and it makes an error – Naveenkumar M Oct 25 '21 at 15:40
  • I tried it with an else condition too. That didn't change anything. The problem appears to be with the fact that the last 'else if' isn't returning `{content}`. – Phill Healey Oct 25 '21 at 15:53
1

You are right that it is a TypeScript error, more specifically, TypeScript expects CardContainer to be a Functional Component, yet your current code makes it possible for the CardContainer to return Undefined, hence the error recognizing the component as type Element | undefined

Without an else condition, the default else behaviour is that it returns cardOutput which is undefined (since it doesn't fall into any of the if or if/else statements defining it).

Samson
  • 1,336
  • 2
  • 13
  • 28