javascript – React Container Components with API calls and error handles

I’m new to programming and even more so in React. My code works but not DRY guidelines. Please help refactor this code. I do not like that the same state is repeated in my container components and the same logic is used in the functions of these components (SetState, error handling and etc.). Thank you!

Api.js

import * as axios from "axios";

const apiKey = process.env.REACT_APP_API_KEY;

const instance = axios.create({
  baseURL: "http://api.football-data.org/v2/",
  method: "GET",
  headers: {
    "X-Auth-Token": apiKey,
  },
});

export const liguesAPI = {
  getLigues() {
    return instance
      .get("competitions?plan=TIER_ONE")
      .then((response) => response.data);
  },
};

export const ligueAPI = {
  getLigue(ligueId) {
    return instance
      .get(`competitions/${ligueId}/matches`)
      .then((response) => response.data);
  },
  getFilteredLigueWithDate(ligueId, dateFrom, dateTo) {
    return instance
      .get(
        `competitions/${ligueId}/matches?dateFrom=${dateFrom}&dateTo=${dateTo}`
      )
      .then((response) => response.data);
  },
};
export const teamAPI = {
  getTeam(teamId) {
    return instance.get(`teams/${teamId}`).then((response) => response.data);
  },
  getTeamMatches(teamId) {
    return instance
      .get(`teams/${teamId}/matches`)
      .then((response) => response.data);
  },
  getFilteredTeamMatchesWithDate(teamId, dateFrom, dateTo) {
    return instance
      .get(`teams/${teamId}/matches?dateFrom=${dateFrom}&dateTo=${dateTo}`)
      .then((response) => response.data);
  },
};

export const teamsAPI = {
  getTeams(ligueId) {
    return instance
      .get(`competitions/${ligueId}/teams`)
      .then((response) => response.data);
  },
};

LigueContainer.jsx

import React from "react";
import Ligues from "./Ligues";
import { liguesAPI } from "../../api/api";
import Preloader from "../common/Preloader/Preloader";
import ErrorModal from "../common/Modal/ErrorModal";

class LiguesContainer extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      ligues: (),
      isFetching: true,
      isError: false,
      errorText: "",
    };
    this.closeErrorModal = this.closeErrorModal.bind(this);
  }

  async componentDidMount() {
    try {
      const data = await liguesAPI.getLigues();
      this.setState({ ligues: data.competitions });
      this.setState({ isFetching: false });
    } catch (e) {
      this.setState({
        errorText: `${e.message}, please reload this page later`,
      });
      this.setState({ isError: true });
    }
  }

  closeErrorModal() {
    this.setState({ isError: false });
  }

  render() {
    const { isFetching, ligues, isError, errorText } = this.state;
    if (isError) {
      return (
        <ErrorModal
          errorText={errorText}
          closeErrorModal={this.closeErrorModal}
        />
      );
    }
    if (isFetching) {
      return <Preloader />;
    }

    return <Ligues ligues={ligues} />;
  }
}

export default LiguesContainer;

TeamsConteiner.jsx

import React from "react";
import Teams from "./Teams";
import { teamsAPI, liguesAPI } from "../../api/api";
import Preloader from "../common/Preloader/Preloader";
import ErrorModal from "../common/Modal/ErrorModal";

class TeamsContainer extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      teams: (),
      ligues: (),
      isFetching: true,
      isError: false,
      errorText: "",
    };
    this.changeLigue = this.changeLigue.bind(this);
    this.closeErrorModal = this.closeErrorModal.bind(this);
  }

  async componentDidMount() {
    try {
      const teamsData = await teamsAPI.getTeams(2021);
      const liguesList = await liguesAPI.getLigues();
      this.setState({
        ligues: liguesList.competitions,
        teams: teamsData.teams,
      });
      this.setState({ isFetching: false });
    } catch (e) {
      this.setState({
        errorText: `${e.message}, please reload this page later`,
      });
      this.setState({ isError: true });
    }
  }

  async changeLigue(ligueId) {
    try {
      this.setState({ isFetching: true });
      const data = await teamsAPI.getTeams(ligueId);
      this.setState({ teams: data.teams });
      this.setState({ isFetching: false });
    } catch (e) {
      this.setState({
        errorText: `${e.message}, please reload this page later`,
      });
      this.setState({ isError: true });
    }
  }

  closeErrorModal() {
    this.setState({ isError: false });
  }

  render() {
    const { isFetching, teams, ligues, isError, errorText } = this.state;
    if (isError) {
      return (
        <ErrorModal
          errorText={errorText}
          closeErrorModal={this.closeErrorModal}
        />
      );
    }
    if (isFetching) {
      return <Preloader />;
    }
    return (
      <Teams teams={teams} changeLigue={this.changeLigue} ligues={ligues} />
    );
  }
}

export default TeamsContainer;
```