I tried to create a simple react native application, and show my position in map, with react-native-maps.
const [coordinate, setCoordinate] = useState()
const getCoordinate = () => {
navigator.geolocation.getCurrentPosition(data => {
setCoordinate({
latitude: data.coords.latitude,
longitude: data.coords.longitude,
});
});
}
useEffect(() => {
getCoordinate();
})
The code works fine, I got my position, marked with a Marker. My problem is why the getCoordinate function calls itself continuously, and running non-stop ?
You are not passing a second argument to the useEffect (which should be an array of dependencies) which is causing it to run on every render.
Since you only want it to run once (essentially on mount), you need to pass an empty array as the second argument to your useEffect:
useEffect(() => {
getCoordinate();
}, [])
Related
I am new in React-Native, I am facing one issue in my app and not able to resolved that yet. All thing is working but first time API being calling two time unnecessary.
Here is my useEffect method :-
useEffect(() => {
if (transactions.length === 0) {
setIsAPICall(true);
}
getTransactions().then((response: any) => {
dispatch(actionTransitionsBadge(0));
setTransactions(response);
setIsAPICall(false);
});
}, [user, onChainBalance]);
In this method I have to get transaction list when component first time open. After that I have to refresh this list when user and onChainBalance get updated. The thing is working but when I am loading this component first time then the api is calling multiple time.
What I can do to manage this flow that once component load then api call once after then when my two state changed the api call again.
Put your getTransactions in the useCallback, like this:
const fetchData=useCallback(
() => {
getTransactions().then((response: any) => {
dispatch(actionTransitionsBadge(0));
setTransactions(response);
setIsAPICall(false);
});
},
[],
)
Then call fetchData in the useEffect
Here is some Details where you can useEffect .
useEffect(() => {},)
useEffect(() => {},[])
useEffect(() => {},[dependency_array])
Here I am explaining them one by one
The first would call on every render
The Second would call two time
the third would call two times and when the dependency array changes
Here is your use Case
useEffect(() => {
if(user !== null && user !== undefined && transactions.length === 0){
getTransactions().then((response: any) => {
dispatch(actionTransitionsBadge(0));
setTransactions(response);
setIsAPICall(false);
});
}
}, [user, onChainBalance]);
but Still this is not a good method. you should use react-query or redux-toolkit-query
i am getting this error mutiple time
You started loading the font "Poppins_400Regular", but used it before it finished loading. You need to wait for Font.loadAsync to complete before using the font.
when run the code
In your apps entry point, usually App.jsx you can render null or a loading state whilst the fonts for your app load, and then once the loadAsync finishes you render your app, something along the lines of:
// App.jsx, or whatever your entry point is
const App = () => {
const [fontLoaded, setFontLoaded] = React.useState(false)
React.useEffect(() => {
Font.loadAsync({
"Poppins_400Regular": require("../path/to/your/font"),
})
.then(() => {
setFontLoaded(true)
})
}, [])
if (!fontLoaded) return null
return (
// All of your normal app ui
)
}
I want to run method when focus screen, i use this:
useEffect(() => {
const unsubscribe = navigation.addListener('focus', () => {
console.log(
'test'
);
});
return unsubscribe;
}, [navigation]);
but it doesnt work. it gives an error like this :
*
An effect function must not return anything besides a function, which
is used for clean-up. You returned: [object Object]
also even i dont return anything, console.log(
'test'
) doest work
I am using navigation V4
Is this working?
import { useFocusEffect } from '#react-navigation/native';
......
useFocusEffect(useCallback(() => {
......
console.log(something)
}, [something]));
//-------
If not check if react navigation is configured correctly.
UPDATE
In React navigation 4.x you will have to follow one of the methods in this guide https://reactnavigation.org/docs/4.x/function-after-focusing-screen/
For useEffect to work properly, the flow is following:
in the square brackets in the end you add a variable which triggers the action. In your case it only triggers on the firs run, and on navigation variable change
you should run your function within useEffect. You have only defined a constant in the body of useEffect, but you never run it.
optionally you may return a function in the end of a run. This function is triggered only when the component unmounts, and used to avoid memory leaks.
Based on this: I'm not sure what are you trying to achieve (unclear from your original post), but this may be what you want:
useEffect(() => {
navigation.addListener('focus', () => {
console.log(
'test'
);
});
const unsubscribe = () => navigation.removeListener('focus'); // !!! I'm not sure about this one, check the docs how to unsubscribe !!!
return unsubscribe;
}, [navigation]); // << triggers useEffect
Assuming you are using the latest version of react-navigation you must the use-focus-effect.
https://reactnavigation.org/docs/use-focus-effect/
Your code should be updated as mentioned below
useFocusEffect(
useCallback(() => {
const unsubscribe = () => {
console.log("test");
}
return () => unsubscribe();
}, [userId])
);
I'm using the action expensesActions.getExpenseList to get a list from the database, which in turns updates the store in expense.expenseList
I'm calling the action inside useEffect hook and would like to get back the list from the store once it's retreived.
My code below is not working because the order is incorrect, if I refresh (with save) I do have the list. How can I change the code so my list is retreived once the actions is complete?
const fetchedList = useSelector(state => state.expense.expenseList);
// Get expense list
useEffect(() => {
const loadList = async () => {
setIsLoading(true)
await dispatch(expensesActions.getExpenseList())
calculateAverageExpense()
}
loadList()
}, [dispatch]);
You can have a second useEffect like this:
useEffect(() => {
if (fetchedList.length) calculateAverageExpense();
}, [fetchedList])
This will execute calculateAverageExpense every time your list change.
As the docs https://reactnavigation.org/docs/en/next/use-focus-effect.html,
"Sometimes we want to run side-effects when a screen is focused. A side effect may involve things like adding an event listener, fetching data, updating document title, etc."
I'm trying to use useFocusEffect to fetch data everytime that the user go to that page.
on my component I have a function which dispatch an action with redux to fetch the data:
const fetchData = ()=>{
dispatch(companyJobsFetch(userDetails.companyId));
};
Actually I'm using useEffect hook to call fetchData(), but I'd like to fetch data everytime that the user go to that page and not only when rendered the first time.
It's not clear from the documentation how to use useFocusEffect and I'm not having success on how to do it.
Any help?
The docs show you how to do it. You need to replace API.subscribe with your own thing:
useFocusEffect(
React.useCallback(() => {
dispatch(companyJobsFetch(userDetails.companyId));
}, [dispatch, companyJobsFetch, userDetails.companyId])
);
For version react navigation 4.x, you can use addEvent listener
useEffect(() => {
if (navigation.isFocused()) {
resetReviews(); // replace with your function
}
}, [navigation.isFocused()]);
OR
useEffect(() => {
const focusListener = navigation.addListener('didFocus', () => {
// The screen is focused
// Call any action
_getBusiness({id: business?.id}); // replace with your function
});
return () => {
// clean up event listener
focusListener.remove();
};
}, []);
For later version 5.x, you can use hooks to achieve this
import { useIsFocused } from '#react-navigation/native';
// ...
function Profile() {
const isFocused = useIsFocused();
return <Text>{isFocused ? 'focused' : 'unfocused'}</Text>;
}