Home > database >  Displaying components from API in an efficient way
Displaying components from API in an efficient way

Time:06-18

I am working on a football team page and due to lack of experience in react i didn't know the most efficient way to display the data i get from my api

What i am currently doing is:

import React,{ useEffect,useState } from 'react'
import '../styles/Players.css'

const Team = () => {

  const [player,setPlayer] = useState([])
  useEffect(()=>{
     axios.get('http://localhost:8080/api/players').then(res=>{
        console.log(res.data)
        setPlayer(res.data)
     }).catch(err =>{
        console.log(err)
     })
  },[])

  return(
    <div className='outside-container'>
      {player.length > 0 && (
        <div className='player-container'>
            <div className='players'>
                          
          {player.map(i => (
            <div className="player" >
              <div className="lastname-background">
                <p className="lastname-paragraph">{i.lastname}</p>
              </div>
              <div className="info" id="info" href="players/{<%= }i.slug }">
                <div className="inline1" id="number">{i.number}</div>
                <div className="inline1" id="firstname">{i.firstname}</div>
                <div className="inline1" id="lastname">{i.lastname}</div>
                <div className="position">{i.position}</div>

              <div className="hidden-stats">
                <div className="inline2">
                  <div className="stat-title">Ημ/νία Γέννησης</div>
                  <div>{i.birthday}</div>
              </div>

              <div className="inline2">
                <div className="stat-title">Συμμετοχές</div>
                <div>{i.appearances}</div>
              </div>

              <div className="inline2">
                <div className="stat-title">Γκολ</div>
                <div>{i.goals}</div>
              </div>
            </div>
          </div>
        </div>
            
          ))}
            </div>
        </div>
      )}
  </div>

  )
}
  
export default Team; 
@font-face {
    font-family: 'Zona Pro Thin';
    font-style: normal;
    font-weight: normal;
    src: local('Zona Pro Thin'), url('/extras/ZonaPro-Thin.woff') format('woff');
}

.page-title {
    font-size: 2.7vw;
    color: white;
    text-align: center;
    padding-top: 50px;
    padding-bottom: 50px;
    background-image: url('https://i.ibb.co/X23sfCZ/3469854-Copy.jpg');
    -webkit-background-size: cover;
    -moz-background-size: cover;
    -o-background-size: cover;
    background-size: cover;
    background-position: center;
    -webkit-box-shadow: inset 0px -50px 25px -10px #1A2434;
    box-shadow: inset 0px -50px 25px -10px #1A2434;
}

.outside-container {
    display: flex;
    justify-content: center;
}

.player-container {
    border-radius: 10px;
    width: 80%;
    background-color: white;
}

.players {
    display: flex;
    justify-content: space-around;
}

h3{
    height: 100px;
    display: flex;
    justify-content: center;
    align-items: center;
    font-size: x-large;
    color: #d14f51;
}

.player{
    position: relative;
    height: 50vh;
    width: 30%;
    -webkit-background-size: cover;
    -moz-background-size: cover;
    -o-background-size: cover;
    background-size: cover;
    background-position: center;
    -webkit-box-shadow: inset 0px -150px 120px -15px #1A2434;
    box-shadow: inset 0px -150px 120px -15px #1A2434;
}

.player:hover{
    cursor: pointer;
}

.info {
    padding-top: 40vh;
    text-align: center;
    color: white;
    z-index: 9;
}

.inline1 {
    display: inline-block;
    vertical-align: middle;
    padding: 5px;
    font-size: 1.7vw;
}

.hidden-stats{
    display: flex;
    justify-content: center;
    visibility: hidden;
    padding-top: 2vh;
}

.inline2{
    width: 7vw;
    border-top: 1px solid rgba(255, 255, 255, 0.308);
    display: inline-block;
    vertical-align: middle;
    padding: 1vh;
}

.stat-title{
    font-size: 0.5vw;
    padding-bottom: 0.5vh;
}
.position{
    font-size: 0.8vw;
}

#number, #lastname {
    font-family: 'Zona Pro Bold';
}

#firstname {
    font-family: 'Zona Pro Thin';
    font-weight: bold;
}

.lastname-background {
    position: absolute;
    padding-top: 35vh;
    width: 100%;
}

.lastname-background p {
    font-size: 4vw;
    font-style: italic;
    color: white;
    opacity: 0.15;
    letter-spacing: 2px;
    text-align: center;
}

My first question is,is there a more efficient way of doing it, and the Second question is how do i manipulate the way they are displayed based on position (like i have done here with vanilla js)

enter image description here

CodePudding user response:

Mapping fetched data is correct approach. Most of the project are doing it the same way. For more advanced code you can add loader while data is fetching and error handling (display error information).

Also optional chaining is useful:

{player?.map(i => (

or conditional rendering:

const [player, setPlayer] = useState([])
const [error, setError] = useState('')
useEffect(() => {
  axios.get('http://localhost:8080/api/players').then(res => {
    console.log(res.data)
    setPlayer(res.data)
  }).catch(err => {
    setError(err.message)
  })
}, [])


{!error && player ? player.map(i => ( /// jsx here
)) : 'loading...'}
{error ? ( <>error</>
) : null}
  • Related