I have a method called sendResults() that makes an API call and does some array manipulation. When I call the method using a "normal" TouchableOpacity button, everything works fine. However, when I call it using a button I have placed in the App Stack header, the method does not run correctly. It feels like an async issue (?) but not sure...
Here is the code for the two buttons.
<TouchableOpacity
onPress={() => {
sendResults(); // works fine
}}
style={styles.buttonStyle}
>
<Text>Save</Text>
</TouchableOpacity>
useEffect(() => {
navigation.setOptions({
headerRight: () => (
<TouchableOpacity
onPress={() => {
sendResults(); // doesn't work
}}
style={styles.buttonStyle}
>
<Text>Save</Text>
</TouchableOpacity>
),
});
}, []);
Edit: sendResults() code
// Shows alert confirming user wants to send results to API
const sendResults = () => {
Alert.alert("Save Results", "Alert", [
{
text: "Save & Quit",
onPress: () => postNumsAndNavigate(),
style: "destructive",
},
{ text: "Cancel", onPress: () => console.log("") },
]);
};
// Save Results button
const postNumsAndNavigate = async () => {
if (bibNums.length == 0) {
alert("You have not recorded any results. Please try again.");
} else if (bibNums.filter((entry) => entry == "").length > 0) {
alert("Blank");
} else {
console.log("\n" + bibNums);
await postNums();
AsyncStorage.setItem(`done`, "true");
navigation.navigate("Home Screen");
}
};
postNums() does an API call.
Edit 2: bibNums declaration
const [bibNums, setBibNums] = useState([]);
You set the handler of the navigation button only once because your useEffect doesn't have any dependency; it runs only when the component is mounted, it captures an old reference of sendResults
. sendResults
changes every time postNumsAndNavigate
and bibNums
change. Add sendResults
to the dependency array to update the navigation button handler every time sendResults
changes.
useEffect(() => {
...
}, [sendResults])
It works correctly for the TouchableOpacity
because you are assigning the handler on every render.
onPress={() => {sendResults()}}