Let's build a Football app with React in 1 hour
Tags: react, javascript, webdev, tutorial
Published: 2022-07-15 09:58:09

Today we are going to build a football app with react. This is the final result we are going to achieve [Football-app](https://sadeedpv.github.io/Footballapi). So let's start.

First, we have to create the react app with the command

```
npx create-react-app footballapp
```

Then, we have to install our dependencies.

```
npm install axios react-bootstrap bootstrap
```
So, let's now clean up the boilerplate code and start fresh. This is our main App.js file:

```
import Navigation from "./components/Navigation";
import Header from "./components/Header";
import Standings from "./components/Standings";
import Highlights from "./components/Highlights";
import Button from "./components/Button";
import Transfer from "./components/Transfer";
import 'bootstrap/dist/css/bootstrap.min.css';

  return (
    <>
    <Navigation />
    <Button /> {* BackToTop Button *}
    <Header />
    <Standings /> {* Important Part *}
    <Transfer />
    <Highlights />
    </>
  );
}

export default App;
```
Since it is impossible for us to cover all these components in this tutorial, we will be covering the standings component in which the league standings are displayed.


![League Standings](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pwfbgyvh7c3hb52wkj7r.png)

Before, we get into the standings component, let me introduce you to the API we are going to use for the project. Here is the [API-link](https://github.com/azharimm/football-standings-api). So, this is how it works "[GET] https://api-football-standings.azharimm.site/leagues" gives the following sample data:

![API Example](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rckdhcsqxjazsfr4r2aj.png)

As you can see, we get back all the leagues available and the league Id. So, in the standings component, we have to create three states with these default values:

```
const [league, setLeague] = React.useState();
const [id, setId] = React.useState('eng.1');
const [season, setseason] = React.useState('2022');
const [tournament, setTournament] = React.useState('Premier League');
```

Now we fetch the data 
Example code:
```
useEffect(() =>{
    axios.get('https://api-football-standings.azharimm.site/leagues').then(res => {
        setLeague(res.data.data)
    }).catch(err =>{
        console.log(err)
    })
},[])

```
Let's create that dropdown menu which enables users to select their desired league.
```
{/* League drop down menu */}
    <Dropdown>
      <Dropdown.Toggle variant="primary">
        Select League
      </Dropdown.Toggle>

    <Dropdown.Menu>
      {league && league.map((league, key) =>{
        return <Dropdown.Item key={key} onClick={() =>{
          setId(league.id)
          setTournament(league.name)
        }}>{league.name}</Dropdown.Item>
      } )}
      
    </Dropdown.Menu>
  </Dropdown>
```
The dropdown component is coming from bootstrap. So, don't forget to import them to the file (Don't forget to import axios as well). Note that, we are mapping through the 'league' state which contains all the league names we need.
Now let's do the same for the 'Select the Year' dropdown menu.

```
const year = ['2010', '2011', '2012', '2013', '2014', '2015', '2016', '2017', '2018', '2019', '2020', '2021', '2022'];
```
We will be providing all the data from 2010.

```
{/* Year dropdown menu */}
    <Dropdown>
      <Dropdown.Toggle variant="primary">
        Select Season
      </Dropdown.Toggle>

    <Dropdown.Menu>
      {year && year.map((year, key) =>{
        return <Dropdown.Item key={key} onClick={() =>{
          setseason(year)
        }}>{year}</Dropdown.Item>
      })}
    </Dropdown.Menu>
  </Dropdown>
```
Now is the important part, which is the Table component. Let's create the Table component and pass the data as props.
```
<Table season={season} id={id} tournament={tournament}/>
```
This is our Table component:
```
  const [team, setteam] = React.useState();

    useEffect(() =>{
        axios.get(`https://api-football-standings.azharimm.site/leagues/${props.id}/standings?season=${props.season}&sort=asc`)
        .then(res => {
            setteam(res.data.data.standings)
        }).catch(err =>{
            console.log(err);
        })
    },[props.id, props.season])
```
We will call the useEffect function whenever the id and season changes.

Our jsx code will look like this:

```
  return (
    <>
<div className='tournament'>{props.tournament} - Season {props.season}</div>

  <div style={{
    display:'flex',
    alignItems:'center',
    justifyContent:'center',
  }}><Table striped hover responsive size={window.innerWidth > 556?'lg':'sm'}>
  <thead>
    <tr>
      <th>#</th>
      <th>Logo</th>
      <th>Name</th>
      <th>Wins</th>
      <th>Loss</th>
      <th>Draws</th>
      <th>Games</th>
      <th>GF</th>
      <th>GA</th>
      <th>Points</th>
    </tr>
  </thead>
  <tbody>
    {team && team.map((team, key) =>{
      return <tr key={key}>
        <td>{key + 1}</td>
        <td><img src={team.team.logos[0].href} alt='team logo' width={window.innerWidth > 556?40:15} height={window.innerWidth > 556?40:15}/></td>
        <td>{team.team.name}</td>
        <td>{team.stats[0].value}</td> {/* wins */}
        <td>{team.stats[1].value}</td> {/* loss */}
        <td>{team.stats[2].value}</td> {/* draws */}
        <td>{team.stats[3].value}</td> {/* games */}
        <td>{team.stats[4].value}</td> {/* GF */}
        <td>{team.stats[5].value}</td> {/* GA */}
        <td style={{
          fontWeight: 'bold'
        }}>{team.stats[6].value}</td> {/* points */}
      </tr>
    })}
  </tbody>
</Table></div>

</>
  )
```
Don't need to worry much if you don't understand the code at the first glance. Here, we are basically using the Table component from bootstrap. The table has a bunch of "th" values and "td" values that is filled with the data we got from the api. We also added a ternary operator to make the table more responsive:
```
 size={window.innerWidth > 556?'lg':'sm'}
```

Note that we haven't added any serious styling to the code. So I will leave that upto you.