简体   繁体   中英

React.js, how to properly use the map() function to display data?

I'm tying to display user data in one of my pages in an electron app. I get the data from firebase/firestore and then put it in an array, then, I want to display that data in a table but I can't manage to display the data on the page.

Here is my code :

function Home() {
  const [allUsers] = useState([]);
  useEffect(() => {
    const fetchData = async () => {
      try {
        const querySnapshot = await getDocs(collection(db, 'users'));
        let allDocs = [];
        querySnapshot.forEach((doc) => {
          allDocs.push({ ...doc.data(), id: doc.id });
        });
        for (const item of allDocs) {
          allUsers.push(item);
        }
      } catch (err) {
        console.log(err);
      }
      console.log(allUsers)
    };
    fetchData();
  }, []);


  return <div className="home">
    {Object.keys(allUsers).map((keyName) => (         
    <p>{allUsers[keyName].firstname}</p>
    ))}
  </div>;
}

Here is how the data looks like :

数据

You should be using a state setter to update allUsers . You are mutating data (anti React pattern). Try doing so (I added comments in the code):

function Home() {
  const [allUsers, setAllUsers] = useState([]); // line I changed
  useEffect(() => {
    const fechedUsers =[];  // line I added
    const fetchData = async () => {
      try {
        const querySnapshot = await getDocs(collection(db, 'users'));
        let allDocs = [];
        querySnapshot.forEach((doc) => {
          allDocs.push({ ...doc.data(), id: doc.id });
        });
        for (const item of allDocs) {
          fechedUsers.push(item);
        }
      } catch (err) {
        console.log(err);
      }
      setAllUsers(fechedUsers) // line I added
    
    };
    fetchData();
  }, []);

  // lines I changed
  return <div className="home">
    {allUsers.map(user => <p>{user.firstname}</p>)}
  </div>;
}

Currently you use Object.keys() to map over the array. When you use this function you receive an array with all the indexes off the array. So this means you will get an array with the data [0, 1, ... ] depending on the length of the data.

But because you use an array you can immediately map over all the objects in the array. Like this:

return <div className="home">
    {allUsers.map((user) => (         
        <p>{user.firstname}</p>
    ))}
</div>

The user variable will be the object you have pushed in the allUsers array. You should also use a state setter like useState

You don't need to use the index to iterate over the response. When you use the map function, you get access to the index as a parameter inside the map function and can use it if needed.

 return (
       <div className="home">
        {allUsers.map((user, index) => {  
          return(
             <div  key={index} className='user-data'>
              //if you're using a table might  need to change the  `p` tag with `td` inside a `tr`
              <p>{user.firstname} </p>
             </div>
           )
        }
        )}
      </div>);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM