Async error in typescript react component

375 Views Asked by At

I have this react component, that I wish to get a payload from api so that the component can use later.

const AccordionCard = async ({username}:AccordionCardProps) =>{
  const repos = await axios.get(`endpoint\${username}`);
  const {data} = repos;
  return(
      <Card style={{ width: '33vh', marginBottom: "5px" }}>
      <Card.Body>
        <Card.Title style={{fontSize: "15px"}}>{username}</Card.Title>
        <Card.Text style={{fontSize: "13px"}}>
          {data ? <p> {data} </p> : null}
        </Card.Text>
      </Card.Body>
    </Card>
  )
}

assuming the data is type string, I found this error when I was using the component Error: 'AccordionCard' cannot be used as a JSX component. Its return type 'Promise' is not a valid JSX element. Type 'Promise' is missing the following properties from type 'ReactElement<any, any>': type, props, key.

What I understand, typescript complains about the component type being a promise element because I use async, but if that was the case, then I could get my data from the api. Can I get the payload directly from the react component? If so how?

PS. the reason why I want to do this, because the payload is coming from each username, and I only have access to this endpoint in order to get the data from each username. So instead of predefining the payload at the beginning, I just wish the endpoint is invoked everytime a component is used for that specific username.

Please help. Thanks.

1

There are 1 best solutions below

2
Kostas Minaidis On

Indeed, you cannot use an async function for a Component. You will need to use a standard function and run the async logic inside a useEffect hook:

const AccordionCard = ({username}:AccordionCardProps) =>{

  // 1) Set a state variable to hold the dynamic data:
  const [ data, setData ] = useState(null);

  // 2) Run the async "side-effect" inside the useEffect:
  useEffect(()=>{
    // 3) Define an async function inside the useEffect callback
    // as the callback cannot be async also
    async function getRepo(){
      try {
        const repos = await axios.get(`endpoint\${username}`);
        setData( repos.data );
      // 4) Handle any network errors.
      } catch(e){
        setData("Error loading user data.");
      }
    }
    // 5) Init the async function
    getRepo();

  },[]);
  return(
      <Card style={{ width: '33vh', marginBottom: "5px" }}>
      <Card.Body>
        <Card.Title style={{fontSize: "15px"}}>{username}</Card.Title>
        <Card.Text style={{fontSize: "13px"}}>
          {data ? <p> {data} </p> : <p>Loading user data...</p>}
        </Card.Text>
      </Card.Body>
    </Card>
  )
}