UseEffect: Invalid hook call. Hooks can only be called inside of the body of a function component
I was trying to get the list of call logs in android using react-native
, I wanted to set up a button
in which when user clicks permission dialog should've appeared, but instead an error appears as I tried to use useEffect
hook as the event
fires and hook rules mentions that
Do not call in event handlers
Tried other possibilities but still not able to reach some solutions.
Here is the code snippet I am using:
const ReadLog = ({ navigation }) => {
const [listData, setListDate] = useState([])
const ReadFromCalLogs = () => {
useEffect(() => {
async function fetchData() {
if (Platform.OS != "ios") {
try {
//Ask for runtime permission
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.READ_CALL_LOG,
{
title: "Call Log Example",
message: "Access your call logs",
buttonNeutral: "Ask Me Later",
buttonNegative: "Cancel",
buttonPositive: "OK",
}
)
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
CallLogs.loadAll().then((c) => setListDate(c))
CallLogs.load(3).then((c) => console.log(c))
} else {
Alert.alert("Call Log permission denied")
}
} catch (e) {
Alert.alert(e.message)
}
} else {
alert(
"Sorry! You can’t get call logs in iOS devices because of the security concern"
)
}
}
fetchData()
}, [])
}
return (
<View>
<View style={styles.ReadFromCallLogs}>
<TouchableOpacity onPress={() => ReadFromCalLogs()}>
<Text style={{ color: "#009387", marginTop: 15 }}>
<MaterialCommunityIcons
size={Dimensions.iconSize}
name="phone-log-outline"
>
</MaterialCommunityIcons>
Read from Call Logs?
</Text>
</TouchableOpacity>
< /View>
</View>
)
}
export default ReadLog
what is the elegant way to do this?
Solution 1:
You can't call a hook inside a function. Hooks can be called only at the top level of the component.
In your code snippet you are calling useEffect()
hook inside a normal function ReadFromCalLogs
this is what causing the error. However, you don't need to call useEffect()
try (Untested):
const ReadFromCalLogs = () => {
async function fetchData() {
if (Platform.OS != "ios") {
try {
//Ask for runtime permission
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.READ_CALL_LOG,
{
title: "Call Log Example",
message: "Access your call logs",
buttonNeutral: "Ask Me Later",
buttonNegative: "Cancel",
buttonPositive: "OK",
}
);
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
CallLogs.loadAll().then((c) => setListDate(c));
CallLogs.load(3).then((c) => console.log(c));
} else {
Alert.alert("Call Log permission denied");
}
} catch (e) {
Alert.alert(e.message);
}
} else {
alert(
"Sorry! You can’t get call logs in iOS devices because of the security concern"
);
}
}
fetchData().catch((e) => {
console.warn(e);
});
};