Home > Blockchain >  Is there any method to store API data in context API?
Is there any method to store API data in context API?

Time:12-26

I want to fetch API data and store it in the context API and use it in other components. The problem is that whenever the page load initially it gives the error of

TypeError: Cannot read properties of undefined

This is maybe due to the fact the API is fetching data afterward and the component is rendering first. Here is my Context code:

 export const CrossRatesProvider = (props) => {
        const [crossRates, setCrossRates] = useState([])
    
        useEffect(() =>{
            async function fetchaud()
        { 
             await fetch('https://freecurrencyapi.net/api/v2/latest?apikey=6cfea260-497f-11ec-94b3-adf08d2418fe&base_currency=AUD')
        .then(res => res.json())
        .then(data => {
            setCrossRates(data);
            console.log(data)
        })
    }
        fetchaud();
         },[])
        const value = {
            crates: [crossRates, setCrossRates]
        }
    
        return (
            <CrossRatesContext.Provider value={value}>
            {props.children}
        </CrossRatesContext.Provider>
            
        )
    }

And this is the component where i am using the context data:

export default function XnaToCountry() {
  const value = useContext(CrossRatesContext);
 const [cRates] = value.crates;
if ( !cRates.length) {
    return null;
  }
  return (
    <div>
       <Table responsive style={{fontSize:"small"}}>
      <tbody>
      <tr>
       <td>{(0.0119063760/cRates.data.AUD).toFixed(9)}</td>
      </tr>
      </tbody>
    </Table>
    </div>
  )
}

CodePudding user response:

Working solution

Context

import { useEffect, useState, createContext } from "react";

export const CrossRatesContext = createContext();

export const CrossRatesProvider = (props) => {
  const [crossRates, setCrossRates] = useState([]);

  useEffect(() => {
    async function fetchaud() {
      await fetch(
        "https://freecurrencyapi.net/api/v2/latest?apikey=6cfea260-497f-11ec-94b3-adf08d2418fe&base_currency=AUD"
      )
        .then((res) => res.json())
        .then((res) => {
          console.log(res.data);
          setCrossRates(res.data);
        });
    }
    fetchaud();
  }, []);
  const value = {
    crates: [crossRates, setCrossRates]
  };

  return (
    <CrossRatesContext.Provider value={value}>
      {props.children}
    </CrossRatesContext.Provider>
  );
};

index.js

import { CrossRatesProvider } from "./context";

const rootElement = document.getElementById("root");
ReactDOM.render(
    <CrossRatesProvider>
      <App />
    </CrossRatesProvider>,
  rootElement
);

Usage

export default function App() {
  const value = useContext(CrossRatesContext);
  const [cRates] = value.crates;
  console.log(cRates);
  return <div></div>;
}

Codesandbox link - https://codesandbox.io/s/elegant-lumiere-emx5k?file=/src/App.js

  • Related