Reuse my custom hook `useFetch` in React? - javascript

I've created a simple useFetch custom hook which allows me to call any Url I want :
import React, { useState, useEffect } from 'react';
export default function useFetch(url) {
console.log(url)
const [data, setData] = useState([]);
useEffect(() => {
fetch(url)
.then((response) => {
if (response.ok) return response.json();
setData([]);
})
.then((data) => {
setData(data)})
.catch((err) => {
console.error(err);
setData([]);
});
}, [url]);
return { data} ;
}
In my Main component I'm loading a static list of items.( via useEffect with [] becuase it's static)
I currently do it via :
export function Courses() {
const [langs, setLangs] = useState([]);
useEffect(() => {
getData(config.url).then((f) => setLangs(f));
}, []);
...
Where getData is:
export function getData(uri) {
return fetch(uri).then(response =>
response.json()
);
}
The problem is that I can't (don't know how) I can use my useFetch here becuase it can't be inside useEffect , and that's why I've created the additional getData method.
ps -
In other "details" component I use useFetch perfectly fine :
export default function Details({ langId }) {
const { data: teachers } = useFetch(`${config.url}/${langId}`);
...
The problem is only in the main component where I don't want to fetch manually . I want to use my useFetch. How can I do that ?
I want that Courses will load the static list only once via useFetch

One possible option is to cache the fetch response (I didn't test the code)
import React, { useState, useEffect } from 'react';
const cache = {};
export default function useFetch(url, useCache=false) {
console.log(url)
const [data, setData] = useState([]);
useEffect(() => {
if (useCache && cache[url]) {
setData(cache[url]);
} else {
fetch(url)
.then((response) => {
if (response.ok) {
const responseData = await response.json();
if (useCache) cache[url] = responseData;
return responseData;
}
setData([]);
})
.then((data) => {
setData(data)})
.catch((err) => {
console.error(err);
setData([]);
});
}
}, [url]);
return { data} ;
}
You can use useRef if you want to keep the hooks as a pure function

Related

Mapping data coming from API

I want to map the data for this app. I can't see the data in the browser window in Reactjs. I tried this:
import React, { useEffect, useState } from "react";
import "../css/Section.css";
const OfferSection = () => {
const [offer,setOffer] = useState([])
useEffect(() => {
const textdes = async () => {
const response = await fetch(`${process.env.REACT_APP_BASEURL}`).then(
(response) => response.json()
);
setOffer(response);
};
textdes();
},[])
return(
<div>
{offer.map((item) => {
{item.payload.map((ip) => {
return (
<img src={ip.data.section2.data[0].image} />
)
})}
})}
</div>
)
}
export default OfferSection;
I want data from this API:
http://192.168.1.175:5000/api/home
Write down the function outside of useEffect and then call it inside UseEffect.
console the response log to see data is comming from API or not
const textdes = async () => {
const response = await fetch(`${process.env.REACT_APP_BASEURL}`).then(
(response) => response.json()
);
console.log(response);
return response;
};
useEffect(() => {
textdes().then((res) => setOffer(res)).catch((err) => console.log(err))
},[]}

change variable value with axios, useeffect, and usestate

i'm newbie here, i'm stuck. i want to change value from false to true, to stop shimmering when data sucessfully to load.
i have action like this
import axios from "axios";
import { CONSTANT_LINK } from "./constants";
import { GET } from "./constants";
import { ERROR } from "./constants";
import { connect } from 'react-redux';
export const addData = () => {
return (dispatch) => {
axios
.get(CONSTANT_LINK)
.then((res) => {
dispatch(addDataSuccess(res.data));
})
.catch((err) => {
dispatch(errorData(true));
console.log("error");
});
};
};
const addDataSuccess = (todo) => ({
type: GET,
payload: todo,
});
const errorData = (error) => ({
type: ERROR,
payload: error,
});
and this is my homepage which influential in this matter
const [shimmerValue, setShimmerValue] = useState(false)
useEffect(() => {
setShimmerValue(true)
dispatch(addData());
}, []);
<ShimmerPlaceholder visible={shimmerValue} height={20}>
<Text style={styles.welcomeName}>Welcome,Barret</Text>
</ShimmerPlaceholder>
i dont understand how it works
You can pass callback like this
const [shimmerValue, setShimmerValue] = useState(false);
const updateShimmerValue = () => {
setShimmerValue(true);
}
useEffect(() => {
// setShimmerValue(true) // remove this from here
dispatch(addData(updateShimmerValue)); // pass callback as param here
}, []);
Callback call here like
export const addData = (callback) => {
return (dispatch) => {
axios
.get(CONSTANT_LINK)
.then((res) => {
....
callback(); // trigger callback like this here
})
.catch((err) => {
....
});
};
};
you can use it:
const [shimmerValue, setShimmerValue] = useState(false)
useEffect(() => {
setState(state => ({ ...state, shimmerValue: true }));
dispatch(addData());
}, [shimmerValue]);

How to connect flask rest API output to react and display result

I am doing inference using flask rest API and I got the result
{
result: {
predictions: -3.4333341121673584
} }
bypassing multiple args in the get as the URL I got the above result
http://127.0.0.1:3000/predict?solute=CC(C)(C)Br&solvent=CC(C)(C)O Now I want to use this result to use in a react app.
I have written the code below
import { useState, useEffect } from "react";
function App() {
const [state, setState] = useState({});
useEffect(() => {
fetch("api/")
.then((response) => {
if (response.status == 200) {
return response.json();
}
})
.then((data) => console.log(data))
.then((error) => console.log(error));
});
I have written the following using a tutorial on the internet. I am new to using fetch API or Axios. Need help to get this result in react app
import { useState, useEffect } from "react";
function App() {
const [data, setData] = useState(null);
const [loading, setLoading = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
fetch("http://127.0.0.1:3000/predict?solute=CC(C)(C)Br&solvent=CC(C)(C)O")
.then((response) => {
if (response.status == 200) {
return response.json();
}
})
.then(setData)
.catch(setError)
.finally(() => setLoading(false));
}, []);
if (loading) {
return <p>Loading</p>
}
if (error) {
return <p>{JSON.stringify(error)}</p>
}
return <p>{JSON.stringify(data)}</p>
}

API giving data in second render in React

I was trying to fetch api with react.js but on first render its gives nothing and the second render its gives data. This makes it so when I try to access the data later for an image I get an error, TypeError: Cannot read property 'news.article' of undefined, because it is initially empty. how can I solve this?
here is my code ..
import React, { useEffect, useState } from 'react';
const HomeContent = () => {
const [news, updateNews] = useState([]);
console.log(news);
useEffect(() => {
const api = 'http://newsapi.org/v2/top-headlines?country=us&category=business&apiKey=940c56bd75da495592edd812cce82149'
fetch(api)
.then(response => response.json())
.then(data => updateNews(data))
.catch((error) => console.log(error))
}, [])
return (
<>
</>
);
};
export default HomeContent;
There is no issue with the code itself, the output you receive is expected. However, you can render the content after it is retrieved as such
import React, { useEffect, useState } from 'react';
const HomeContent = () => {
const [news, updateNews] = useState([]);
const [isLoading, setIsLoading] = useState(true);
console.log(news);
useEffect(() => {
const api = 'http://newsapi.org/v2/top-headlines?country=us&category=business&apiKey=940c56bd75da495592edd812cce82149'
fetch(api)
.then(response => response.json())
.then(data => {
updateNews(data.articles);
setIsLoading(false);
})
.catch((error) => {
console.log(error);
setIsLoading(false);
})
}, [])
return (
<>
{isLoading ?
<p>Loading...</p> :
// Some JSX rendering the data
}
</>
);
};
export default HomeContent;

Export a function which has an imported axios response data

Currently I have two files, one is being used to fetch and get the data response. The other js file is to import these results in a function. I would like to export this last function so I could use it in other files.
api.js
import axios from 'axios';
const url = 'data/data.json';
const cars = 'data/cars.json';
export const fetchData = () => {
return axios.get(url)
.then(response => {
return response.data
})
}
export const fetchCars = () => {
return axios.get(cars)
.then(response => {
return response.data
})
}
import.js
See: export const details
import { fetchData, fetchCars } from './api';
let fetchingData = fetchData();
let fetchingCars = fetchCars();
// I want to export the below functionality:
fetchingData.then((result) => {
// I will be doing stuff here
console.log(result);
})
export const details = () => {
fetchingCars.then((result) => {
// I will be doing stuff here
console.log(result);
})
}
// And be able to console.log the results out of that exported function. Since I will need to update DOM values based on the API results.
console.log(details);
importCars.js
import { details } from './import'
function example() {
// do something
details();
}
Just change the fetchData in api.js as below,
export const fetchData = () => {
return axios.get(url)
}
And in import.js use result.data instead of result while logging like below,
fetchingData.then((result) => {
// I will be doing stuff here
console.log(result.data);
})

Categories

Resources