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