无效钩子调用React Native



我在RN中有一个无效的钩子错误。我使用按钮单击事件处理程序来执行倒计时计时器的setInterval函数。

Error: 'Hooks只能在函数组件的内部调用。(…)">

我代码:

import { Button, StatusBar, StyleSheet, Text, TouchableOpacity, View } from 'react-native'
import React, { useEffect, useState } from 'react'
import { Ionicons } from '@expo/vector-icons'
import { AntDesign } from '@expo/vector-icons'
export default function MenuBar() {
const [time, SetTime] = useState(10);
const startTime = () => {
useEffect(() => {
const interval = setInterval(() => {
if(time > 0) {
SetTime(time => time - 1);
} else {
SetTime(time => time + 10);
} 
}, 1000);
return () => clearInterval(interval);
}, []); 
}
return (
<View style={styles.container}>
<Button color="orange" onPress={startTime} title="Start Time!!"></Button>
<View style={styles.menu}>

<TouchableOpacity>
<AntDesign style={[styles.button, styles.exitBtn] } name="logout" size={24} color="white" />
</TouchableOpacity>

<TouchableOpacity>
<AntDesign style={styles.button} name="questioncircleo" size={24} color="white" />
</TouchableOpacity>
<Text style={styles.timer}>{time}</Text>
<TouchableOpacity>
<AntDesign style={styles.button} name="picture" size={24} color="white" />
</TouchableOpacity>
<TouchableOpacity>
<AntDesign style={styles.button} name="sound" size={24} color="white" />
</TouchableOpacity>
</View>
</View>
)
}

你不能在另一个函数中调用钩子,除非这个函数是React组件。

当你想在按下按钮时启动定时器,你不需要听副作用,因此不需要调用useEffect,只要在按下按钮时启动定时器。

卸载组件时需要清除计时器。为此,你需要一个useEffect,因为React内部会触发useEffect清理函数。

我建议这样做:

export default function MenuBar() {
const interval = useRef(null)
const [time, setTime] = useState(10);
const startTime = () => {
if (interval.current) {
// Making sure not to start multiple timers if one
// has already started
clearInterval(interval.current);
}
interval.current = setInterval(() => {
if (time > 0) {
setTime(time => time - 1);
} else {
setTime(time => time + 10);
}
}, 1000);
}
// only use useEffect when unmounting the component
// and calling the cleanup function
useEffect(() => {
return () => {
if (interval.current) {
return clearInterval(interval.current);
}
};
}, []);
return (
// rest of component
)

最新更新