how to load a function when a page load react native - reactjs

I'm using react-native with hooks, and I'm trying to load a JSON from AsyncStorage every time a user opens one of my react-native screens This JSON contains information on what my states should be set to.
How can I call a function that runs every time this screen is opened?
i know that without hooks this should be done with useEffect, but when i put my api call there it makes an error
this is my code
useEffect(() => {
const getKind = () => {
ForceApi.post(`/GetKindPensionController.php`)
.then(res => {
setpPensionKind(res.data.pension);
})
}
}, []);

You are missing call the getKind, and it should be a async function! For a better code try something like:
useEffect(() => {
async function getKind() {
const { data } = await ForceApi.post(`/GetKindPensionController.php`)
setpPensionKind(data.pension);
}
getKind();
}, []);

Related

How do i put a setstate function that is already within an async function, within a useEffect hook?

I am working on a project, which is a django project with REACT as the frontend. For the homepage, there is a useState variable ('room_code') that is used. The setstate variable is set_room_code. So, i have an async function that fetches the room code from an api and then the idea is to use the set_room_code hook. But this is just not working. The issue is with the set_room_code as the code works if i simply remove it. I have tried to search up ideas but i am short on it. Any input would be appreciated.
useEffect( () => {
let fetch_code = async () => {
const response = await fetch('/api/user-room');
const data = await response.json();
console.log('hi');
console.log(data.room_code);
console.log('bhao');
set_room_code(data.room_code);
};
fetch_code();
console.log(hi);
}, []);
I have tried using an extra useEffect hook but that doesnt work as well
A few things, first its best practice to name the useState variable
const [roomCode, setRoomCode] = useState();
FYI.
Now as to your question--
useEffect( () => {
let fetch_code = () => {
fetch('/api/user-room').then((data) => {
setRoomCode(data.room_code);
console.log(data.room_code);
return response.json();
});
};
fetch_code();
console.log("this should show your RoomCode", roomCode)
}, [roomCode]);

What's the best practice of calling API data from a function outside useEffect?

While working with react useEffect hook, most of the example I came across in case of calling api data in useEffect hook for initiate the component is, calling api directly inside useEffce hook.
For instance,
useEffect(() => {
async function(){
const res = await axios.get(`https://jsonplaceholder.typicode.com/${query}`);
setData(res.data)
}
}, []);
But what about fetch data outside the hook with a method ? For instance,
const getData = () => {
async function(){
const res = await axios.get(`https://jsonplaceholder.typicode.com/${query}`);
setData(res.data)
}
useEffect(() => {
getData(); // here eslint shows an warning "Promise returned from setData is ignored"
}, [])
is there any specific reason for avoiding second example. If not what's the proper way to call api call function in useEffect hook with proper cleanup ?
In React component file
useEffect(() => {
loadData(query).then(setData)
}, [query])
crate another service file to serve data from API
in service file
export const loadData = async query => {
const res = axios.get(`https://jsonplaceholder.typicode.com/${query}`);
return res.data;
// You can put this API call in try catch to handle API errors
};
Creating a separate function for calling an api is a perfect example of loading data in useEffect. You can give it parameters if you would have a paginated endpoint and call it multiple times or add polling to the page to load the data by interval. I can only see benefits by creating a function for this.
useEffect(() => { fetch("./product.JSON") .then(res => res.json()) .then(data => setProducts(data)) }, [])

React: how can I process the data I get from an API before I render it out?

I have no issues fetching the data from an API using useEffect. That works fine.
The problem is that I need to apply some processing to the data before I actually render it out (in this case, I need to shuffle the array that I receive).
I tried a million different ways, but I just can't find the right place to write that logic. Basically, it won't work anywhere.
What is the right way of going about this?
you can do everything with data before setState.
is useEffect when you fetched data from Api, shuffle it and then do setState.
little example:
useEffect(() => {
axios.get("http://example.com/data").then(response => {
const data = shuffle(response.data);
setState(data);
})
});
useEffect(() => {
const fetchData = async () => {
await axios.get("http://example.com/data").then(response => {
const data = shuffle(response.data);
setState(data);
});
};
fetchData();
return () => {
// Clean up func
}
}, []); //[] will prevent infinite API calling.

React Component gets unmounted and i don't know why

I'm a completely new to the whole react world but I'm trying to develop a SPA with a integrated calendar. I'm using react-router for routing, react-big-calendar for the calendar, axios for my API calls and webpack.
Whenever I'm loading my Calender Component it gets mounted and unmounted several times and I think that causes my API call to never actually get any data. I just can't figure out what is causing this.
The Code:
useEffect(() => {
console.log("mounting Calendar")
let source = Axios.CancelToken.source()
if(!initialized) {
console.log("getting Data")
getCalendarEvents(source)
}
return () => {
console.log("unmounting Calendar")
source.cancel();
}
})
const getCalendarEvents = async source => {
setInitialized(true)
setLoading(true)
try {
const response = await getCalendar({cancelToken: source.token})
const evts = response.data.map(item => {
return {
...item,
}
})
calendarStore.setCalendarEvents(evts)
} catch (error) {
if(Axios.isCancel(error)){
console.log("caught cancel")
}else{
console.log(Object.keys(error), error.message)
}
}
setLoading(false)
}
This is the result when i render the component:
Console log
If you need any more code to assess the problem, I will post it.
I appreciate any kind of input to solve my problem.
Thank you
Its because of the useEffect. If you want it to run just once on mount you need to pass an empty array as a dependency like so :
useEffect(() => {
console.log("mounting Calendar")
let source = Axios.CancelToken.source()
if(!initialized) {
console.log("getting Data")
getCalendarEvents(source)
}
return () => {
console.log("unmounting Calendar")
source.cancel();
}
},[])
This means it will only run once. If there is some state or prop you would like to keep a watch on you could pass that in the array. What this means is that useEffect will watch for changes for whatever is passed in its dependency array and rerun if it detects a change. If its empty it will just run on mount.

I cannot collect data from API using Axios + React

I'm beginner with React. I have 2 different cases where I'm using React Hooks which I cannot receive the data from my local API properly.
Case 1:
export const RegisterT = () => {
const [test, setTest] = useState()
const addrState = {}
axios.get('http://127.0.0.1:3333/states', { addrState })
.then(res => {
setTest(res.data)
console.log(test)
})
...
}
It works with the state test displaying correctly the content from the API but I don't know why/how the Axios continues calling the API infinity - endless. (Ps: the very first call it returns undefined, then the next ones it works) What am I doing wrong?
To fix this I've tried to use useEffect like this (Case 2):
export const RegisterT = () => {
const [test, setTest] = useState()
const addrState = {}
useEffect(() => {
axios.get('http://127.0.0.1:3333/states', { addrState })
.then(res => {
setTest(res.data)
console.log(test);
})
}, [])
...
}
Now the Axios works only once but no data is coming from the API. Maybe I should use async/wait for this case but I cannot make it work. Does anyone know how to fix that (Case 1 or/and Case 2)?
Thanks.
Updating the state is an asynchronous operation. So the state is not really updated until the next time the component gets rendered. If you want to capture the correct state, you can either console.log(res.data) or wrap that inside the useEffect hook with test as dependency.
export const RegisterT = () => {
const [test, setTest] = useState()
const addrState = {}
// effect only runs when component is mounted
useEffect(() => {
axios.get('http://127.0.0.1:3333/states', { addrState })
.then(res => {
setTest(res.data);
});
}, []);
// effect runs whenever value of test changes
useEffect(() => {
console.log(test);
}, [test]);
}
That way it is guaranteed that the console.log runs when the value of test is updated.
Also the reason the API request is invoked once is you have not mentioned anything in the dependency array. [] empty dependency array runs the effect when the component is mounted for the first time.
async/await is just a wrapper around Promise object. So they would behave similarly.
The solution with useEffect is good. If you don't use it each render will call the request. This is the same if you put there console.log with any information. The reason why you don't see the data in the useEffect is that the value of the state is not updated in current render but in the next which is called by setter of the state. Move the console.log(test); after useEffect to see the data. On init it will be undefined but in the next render, it should contain the data from the request.

Resources