skip to Main Content

I’m trying to display the users name from a firebase db within a react return function.

I have a function called getUserName which retrieves the username from the db and returns it.

const getUserName = async () => {
        try {
            const docRef = doc(db, "users/" + auth.currentUser?.uid);
            const userDocument = await getDoc(docRef);
            const userData = userDocument.data() as UserData;
            const userName = userData.name.split(' ')[0];
            return userName;
        } catch (error) {
            console.error(error)
            return "Failed to Retrieve UserName";
        };
    }

Then I’m trying to display it in the react component’s return.

return (
  <div>
    Hi, {getUserName()}!
  </div>
)

But I’m getting this error:
Type 'Promise<string>' is not assignable to type 'ReactNode'.ts(2322) const getUserName: () => Promise<string>

Not sure what I’m doing wrong here. I’m using TypeScript so do I need to specify the type somewhere?

2

Answers


  1. the error info is pretty clear.
    to fix this, you can modify the getUserName function to use the useState hook to store the username and update it asynchronously.

    import { useState, useEffect } from 'react';
    
    const MyComponent = () => {
      const [userName, setUserName] = useState('');
    
      useEffect(() => {
        const getUserName = async () => {
          try {
            // some code here
            setUserName(userName);
          } catch (error) {
            console.error(error);
            setUserName("Failed to Retrieve UserName");
          }
        };
        getUserName();
      }, []);
    
      return (
        <div>
          Hi, {userName}!
        </div>
      );
    };
    
    Login or Signup to reply.
  2. I’d suggest putting the API call into a React.useEffect() and storing it in state. React expects a ReactNode as indicated in the error, but your function is returning a promise (via async). React does not resolve it in the return statement.

    function functionalComponent() {
     const [username, setUsername] = getState('foo');
    
     useEffect(() => {
      // async IIFE
      (async () => {
       const username = await db.getUsername();
       setUsername(username);
      })();
     }, []); // <- Indicates to run this once on mount
    
     return <>{username}</>;
    }
    
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search