React Hook useEffect I can't get the data - reactjs

I want to get real time bitcoin information but datas not coming. I get this error = React Hook useEffect has a missing dependency: 'coinData'. Either include it or remove the dependency array
const [coinData,setCoinData] = useState([]);
useEffect(() => {
const getData = async () =>{
const baseURL = "https://api.coingecko.com/api/v3/coins/bitcoin?tickers=true&market_data=true&community_data=true&developer_data=true&sparkline=true"
const response = await axios(baseURL)
setCoinData(response);
console.log(coinData)
}
getData();
}, []);

The error is because you're using coinData (state) inside useEffect.
If you add coindData to the dependencies array, you'll get an infinite loop.
To log the response use console.log(response), not console.log(coinData).
useEffect(() => {
const getData = async () =>{
const baseURL = "https://api.coingecko.com/api/v3/coins/bitcoin?tickers=true&market_data=true&community_data=true&developer_data=true&sparkline=true"
const response = await axios(baseURL)
setCoinData(response);
console.log(response);
}
getData();
}, []);

Related

React Hook useEffect has a missing dependency: 'tasks'. Either include it or remove the dependency array

I get data from backend and set to my state in componentdidmount but value not set after log state
const [tasks, setTasks] = useState([]);
const getTasks = async () => {
const getTodoInformation = {
email: localStorage.getItem("tokenEmail"),
};
if (getTodoInformation.email) {
const response = await axios.post(
"http://localhost:9000/api/todo/get",
getTodoInformation
);
setTasks(response.data.data);
}
};
useEffect(() => {
getTasks();
console.log(tasks);
}, []);
My tasks is empty when i log it
So the title and the question itself are actually two questions.
React Hook useEffect has a missing dependency: 'tasks'. Either includes it or remove the dependency array
That's because you include a state (i.e. tasks) in the useEffect hook. And React is basically asking you, "Do you mean run console.log(tasks) every time tasks is updated?". Because what you are doing is run the useEffect hook once and only once.
And for your "actual" question
value not set after log state
In short, states are set in async manner in React. That means tasks is not necessary immediately updated right after you call setTasks. See #JBallin comment for details.
const [tasks, setTasks] = useState([]);
useEffect(() => {
setTimeout(async () => {
const getTodoInformation = {
email: localStorage.getItem("tokenEmail"),
};
if (getTodoInformation.email) {
const response = await axios.post(
"http://localhost:9000/api/todo/get",
getTodoInformation
);
setTasks(response.data.data);
}
}, 1000);
console.log(tasks);
}, []);
The main problem is that useEffect -> is a sync method, getTasks() is asynchronous, and useEffect only works once when your component mounts. Shortly speaking, you got your data from the backend after useEffect worked.
For example, if you will add one more useEffect
useEffect(() => {
console.log(tasks);
}, [tasks]);
You will see log, after your data will have changed.
You can use self-calling async function inside useEffect as shown here:
const [tasks, setTasks] = useState([]);
const getTasks = async () => {
const getTodoInformation = {
email: localStorage.getItem("tokenEmail"),
};
if (getTodoInformation.email) {
const response = await axios.post(
"http://localhost:9000/api/todo/get",
getTodoInformation
);
return response.data.data;
}
};
useEffect(() => {
(async () => {
const tasks = await getTasks();
setTasks(tasks);
})();
console.log(tasks);
}, [tasks]);

Need router.query variable passed to API URL call, but is undefined on first render

I have the following API Call:
const router = useRouter();
const { albumQuery } = router.query;
const [albums, setAlbums] = useState([]);
const fetchAlbumsHandler = useCallback(async () => {
setIsLoading(true);
setError(null);
try {
const url = `http://ws.audioscrobbler.com/2.0/?method=album.search&album=${albumQuery}&api_key=MY_API_KEY&format=json`;
const res = await fetch(url);
const data = await res.json();
if (!res.ok) {
throw new Error("Something went wrong!");
}
const jsonAlbums = data.map(
// JSON business Logic
);
setAlbums(transformedAlbums);
} catch (error) {
setError(error.message);
}
setIsLoading(false);
}, []);
With the corresponding useEffect function:
useEffect(() => {
fetchAlbumsHandler();
}, [fetchAlbumsHandler]);
However, the API call takes ${albumQuery} as undefined on the first render due to NextJS implementation details. Is there a way for me to access the variable on the first render?
No, if the albumQuery isn't available on the initial render then the code should handle waiting for it to become available.
The existing code is assuming albumQuery is available on the initial render and attempts to close it over in the useCallback hook. After this the useEffect hook is called and since fetchAlbumsHandler is now a stable reference the useEffect hook won't be retriggered nor will fetchAlbumsHandler be re-memoized since the useCallback hook has an empty dependency array.
Minimally albumQuery appears to be a dependency for the useCallback hook and/or the useEffect hook. If fetchAlbumsHandler isn't passed as a prop to children there's no real benefit to memoizing it. I suggest moving it into the useEffect hook callback and using albumQuery as a dependency.
Example:
const router = useRouter();
const { albumQuery } = router.query;
const [albums, setAlbums] = useState([]);
useEffect(() => {
const fetchAlbumsHandler = async () => {
setIsLoading(true);
setError(null);
try {
const url = `http://ws.audioscrobbler.com/2.0/?method=album.search&album=${albumQuery}&api_key=MY_API_KEY&format=json`;
const res = await fetch(url);
const data = await res.json();
if (!res.ok) {
throw new Error("Something went wrong!");
}
const jsonAlbums = data.map(
// JSON business Logic
);
setAlbums(transformedAlbums);
} catch (error) {
setError(error.message);
}
setIsLoading(false);
}
fetchAlbumsHandler();
}, [albumQuery]);

How to async fetch data in useEffect

I have some issue. When I do to async fetch data (using axios for fetching) in the useEffect, and after I set responsed data to state, using a useState hook. And page render befor then I got response from server.
For demonstration this issue I have putted console.log for get current state, and I get 'undefined':
const [positions, setPositions] = useState([]);
useEffect(() => {
const fetchPositions = async () => {
const response = await EmployeeService.getEmployeePositions();
setPositions(response.data);
};
fetchPositions();
console.log('positions from state: ', positions); //undefined
}, []);
Method for fetching data from "EmployeeService":
getEmployeePositions(){
return axios.get(EMPLOYEE_API_BASE_URL + '/positions');
}
Thanks in advance, and best regards!
React needs to re-render to display the results.
Which means you need to capture the result on the subsequent re-render that is caused when you setState.
Move the console log outside of the useEffect
const [positions, setPositions] = useState([]);
useEffect(() => {
const fetchPositions = async () => {
const response = await EmployeeService.getEmployeePositions();
setPositions(response.data);
};
fetchPositions();
}, []);
console.log('positions from state: ', positions); // NOT UNDEFINED
React will always render once before you have data.
So you can catch it with a condition.
if (positions.length === 0) {
return null;
}
nothing wrong with your code, useEffect is always undefined because it read the first value of your rendered app.
To update state in useEffect put paramater on the array [] but in your case it will cause an infinity loop.
try logging inside the async function instead
const [positions, setPositions] = useState([]);
useEffect(() => {
const fetchPositions = async () => {
const response = await EmployeeService.getEmployeePositions();
setPositions(response.data);
console.log('data from response: ', response);
};
fetchPositions();
}, []);
or do it like this
const [positions, setPositions] = useState([]);
useEffect(() => {
const fetchPositions = async () => {
const response = await EmployeeService.getEmployeePositions();
setPositions(response.data);
console.log('data from response: ', response);
};
if((positions ?? []).length == 0){
fetchPositions();
console.log('this is position state before fetch~>',positions)
} else{
console.log('this is position state after fetch~>',positions)
}
}, [positions]);

How do i fix the react useEffect problem?

Iam a new to react and recently i just have just been practicing react by making a simple shopping cart functionality
this is part of the code i get the error from:
const MainShop = () => {
const [products, setProducts] = useState([]);
const [category, setCategory] = useState('');
const [sort, setSort] = useState('');
const [filteredProducts, setFilteredProducts] = useState([]);
useEffect(() => {
const fetchItems = async () => {
const data = await fetch('https://fakestoreapi.com/products');
const items = await data.json();
console.log(items);
setProducts(items);
setFilteredProducts(products);
};
fetchItems();
}, []);
the error says:
Line 42:6: React Hook useEffect has a missing dependency: 'products'. Either include it or remove the dependency array. You can also replace multiple useState variables with useReducer if 'setFilteredProducts' needs the current value of 'products' react-hooks/exhaustive-deps
how do i solve this problem?
Basically, you should first learn what is useEffect Dependency Array. Also in your question define the states you are using and where are you getting products what is the difference with fetched items. If they are different is it necessary to keep them in the same useEffect hook? Note that you can have several effect hooks in one component with different dependencies array
But as a fast hack, if you want the fetch to be triggered only once when the component mounts, disable the dependency error like below.
useEffect(() => {
const fetchItems = async () => {
const data = await fetch('https://fakestoreapi.com/products');
const items = await data.json();
console.log(items);
setProducts(items);
setFilteredProducts(products);
};
fetchItems();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
If according to filters the fetch should be triggered again
useEffect(() => {
const fetchItems = async () => {
const data = await fetch(`https://fakestoreapi.com/products?filter=${filters}`);
const items = await data.json();
console.log(items);
setProducts(items);
setFilteredProducts(products);
};
fetchItems();
}, [filters]);

Correct dependency array for useEffect with React hooks

I am using Create-React-App and the (excellent) use-http for a custom useFetch hook. The goal is to make several API calls upon login to an account area:
const [user, setUser] = useState(null)
const [profile, setProfile] = useState(null)
const [posts, setPosts] = useState(null)
const request = useFetch('/')
const initializeAccount = async () => {
try {
const user = await request.get('api/user/')
const profile = await request.get('api/profile/')
const posts = await request.get('api/posts/')
if (user) {
setUser(user.data)
}
if (profile) {
setProfile(profile.data)
}
if (posts) {
setPosts(posts.data)
}
} catch (e) {
console.log('could not initialize account')
}
}
useEffect(() => {
initializeAccount()
return () => console.log('unmount')
})
I have tried using [] as the dependency array, but I get a linting error saying to move initializeAccount to the dependency array. If I add it, the function runs endlessly.
What is the correct way to setup the dependency array so that this function is called one time? Also, what would be the correct way to handle abort of each of the API calls in this scenario?
My man, in order to run useEffect once for api calls, you have to do it like this:
useEffect(() => {
initializeAccount()
return () => console.log('unmount')
},[])
Hope it helps.

Resources