react-native not rendering the response of axios response - reactjs

I have written an axios request in react-native useEffect.The request is succesfull in backend and returning a the right response in terminal.But the useEffect hook is not working according to it .It is still returning product as undefined and not changing the state.
If it all works well the product would contain the product variable.
It only works when I save it again and then it shows the product . Am I missing something here ?
Thanks in Advance !!
const [product, setProduct] = useState();
useEffect( () => {
getproductinfo()
if (props.editMode) {
AsyncStorage.getItem("jwt")
.then((res) => {
setToken(res);
})
.catch((error) => console.log(error));
}
console.log(product, "this is product");
},
[],
)
this is my function
const getproductinfo = async () => {
await axios
.get(`${baseURL}products/get/product/${props.product}`)
.then((res)=> {setProduct(res.data)
})
.catch((error)=> {
console.log(error);
console.log("this is order card product card error ")
});
}

getproductinfo is an async function and you don't use await in the useEffect hook so the code continues to run while the axios request is not yet resolved. However you can't use an async function as useEffect so I suggest the following approach
useEffect( () => {
const asyncFunction = async() {
await getproductinfo();
console.log(product, "this is product");
}
asyncFunction();
// Rest of your code....
},
[],
)

Related

Why axios get request hit again and again in React my following code

when I am reload page then this request hit again and again
const [adminRequestData, setadminRequestData] = useState([]);
// admin Request
axios
.get("/requestForAdmin")
.then((result) => {
setadminRequestData(result.data);
})
.catch((err) => {
console.log(err);
});
This is because a function component executes the whole body of the function whenever there is a state change, You should wrap your Axios call in the useEffect hook
const [adminRequestData, setadminRequestData] = useState([]);
useEffect(() => {
// admin Request
axios
.get("/requestForAdmin")
.then((result) => {
setadminRequestData(result.data);
})
.catch((err) => {
console.log(err);
});
}, []);
Check more about managing state in react here

React useEffect calls API too many time, How can I limit the API call to only once when my component renders?

I am calling a get API in useEffect hook, to get the data before component mounts,
but it's calling the API to many time and I am getting an error "To many API calls".
const [total, setTotal] = useState(0);
const [message, setMessage] = useState('');
useEffect(() => {
covidApi.getData({url:'/totals'})
.then((response) => {
setTotal(response.data[0]);
setMessage('');
console.log(response.data);
})
.catch((error) => {
setMessage("No data found");
console.log(error);
})
});
Output:
Please let me know is it the best way to get data from API before your component renders using useEffect hook.
Put a [] after the function in useEffect like this:
useEffect(() => {
covidApi.getData({url:'/totals'})
.then((response) => {
setTotal(response.data[0]);
setMessage('');
console.log(response.data);
})
.catch((error) => {
setMessage("No data found");
console.log(error);
})
}, []);
This will call the API only once.

How to use fetch function and show api response on component ? Custom fetch response is not passing to component

After Fetch /Vehicles from api I wanted to show them in component but inside useFetch function I can console.log res.data but inside the Trucks component I could not map trucks.
My Custom useFetch function:
import { useState, useEffect } from 'react';
import axios from 'axios';
const useFetch = (url) => {
const api = axios.create({
baseURL: 'api url',
headers: { Authorization: `Bearer ${localStorage.token}` },
});
const [data, setData] = useState(null);
const [isPending, setIsPending] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
const abortCont = new AbortController();
setTimeout(() => {
api
.get(url)
.then((res) => {
console.log(res.data);
if (!res.ok) {
throw Error('Could not with fetch data');
}
})
.then((data) => {
data.json();
console.log(data);
setIsPending(false);
setError(null);
})
.catch((err) => {
if (err.name === 'AbortError') {
console.log('fetch aborted');
} else {
setIsPending(false);
setError(err.message);
}
});
}, 1000);
return () => abortCont.abort();
}, [url]);
return { data, isPending, error };
};
export default useFetch;
I used this custom useFetch function and could get data (inside the function) its not usable to render
Some possible reasons I thought ;
useFetch function may not return data properly
I may need to use stringify or json function for API respond
Trucks Component:
const Trucks = () => {
const { data: trucks, error, isPending } = useFetch('/vehicles');//
console.log('they are ' + { trucks }); //console output ->[object,Object]
return (Some Jsx)};
export default Trucks;
Thanks
There are two issues with your Hook itself that I can see.
The first thing is that you never call setData. This means that although you are fetching the data inside your hook and consoling it out, you never set the data object to hold the retrieved data.
The second thing is that the second then isn't actually doing anything with the data you are retrieving. You can handle this all inside the first statement as such
.then((res) => {
setData(res.data);
setIsPending(false);
if (!res.ok) {
setIsPending(false);
throw Error("Could not with fetch data");
}
})
Once you do this you should be able to call your hook inside the related component, and render it using some JSX. Just make sure to add a check for isPending and display some sort of loading screen before actually rendering your data.
Another note, when you use axios, you do not need to call data.json(). That is something that is required for the fetch API but axios just requires you to call res.data when resolving the promise

Why is my React useEffect not loading again when I refresh the page?

I am using a useEffect to get information from firebase and set my redux state thereafter. When I open the page for the first time, all my components contain the correct information. As soon as I refresh the page, all the information is set to nothing? I think it is because the useEffect does not execute again for some reason. Here is my code below:
useEffect(async () => {
setLoading(true);
const fetchData = async () => {
await getConfigs().then((response) => {
const obj = response;
setRedux(obj[0]);
});
};
fetchData();
}, []);
I think the problem is that you provide an async function as a callback to useEffect, which is not allowed. Just get rid of it, like so:
useEffect(() => {
setLoading(true);
const fetchData = async () => {
// Also, you either await or use .then(), not both
const response = await getConfigs();
const obj = response;
setRedux(obj[0]);
};
fetchData();
}, []);

Update react-native state using async/await

I am trying to immediately update a boolean state variable in react native. the await keyword does not work however. because state setter functions are asynchronous, how can I do this using async / await? In vscode, the await in front of the setLike setter function has a message : "await has no effect on this type of expression"
const likeIt = async () => {
console.log('like pressed');
console.log('liked? before set', like); //**false**
await setLike(like => !like);
console.log('liked? after set', like); //**should be true but getting false**
const axiosAuth = await axiosWithAuth();
const userToken = axiosAuth.defaults.headers.Authorization;
if (like) {
axiosAuth.post(`https://url`,{})
.then(res => {
console.log('response from post like: ', res.data);
})
.catch(err => console.log('error in post like', err.message))
} else {
axiosAuth.delete(`https://url`)
.then(res => console.log('res from unlike', res.data))
.catch(err => console.log('err from unlike', err))
}
}
If we talk about react hooks, you should to know that useState() return array of two values. The second value is a dispatch function which we use to change value of state. And this functions are synchronous.
In your example this dispatch function is setLike() (and it is synchronous function). So await keyword do not work for them actually.
React has special system in the hood to work with changing state. This system wait for batch of changing states and then update our state and rerender component. Before that update of state and rerender of component, our likeIt() function will be done.
You could use useEffect() lifecycle method to handle change of like state.
For example:
const likeIt = async () => {
console.log('like pressed');
console.log('liked? before set', like); //**false**
await setLike(like => !like);
}
useEffect(() => {
console.log('liked? after set', like); //**true**
...
}, [like]);
await useState(); will not work.
Here is a possible solution that rather works with a temp variable in your likeIt() function.
function App() {
const [like, setLike] = useState(false);
const likeIt = async () => {
let temp = !like;
const axiosAuth = await axiosWithAuth();
const userToken = axiosAuth.defaults.headers.Authorization;
if (!temp) {
axiosAuth.delete(`https://url`)
.then(res => console.log('res from unlike', res.data))
.catch(err => console.log('err from unlike', err))
} else {
axiosAuth.post(`https://url`,{})
.then(res => {
console.log('response from post like: ', res.data);
})
.catch(err => console.log('error in post like', err.message))
}
setLike(temp);
}
return (
<div className="App">
<button onClick={likeIt}>{like === true ? 'Liked' : 'Not Liked'}</button>
</div>
);
}
Are you getting compiling errors due to await setLike()?
If not, it is a small issue that would be confusing for some people on VScode.
Please kindly check https://github.com/microsoft/vscode/issues/80853

Resources