Tengo un error de enlace no válido en RN. Estoy usando un controlador de eventos de clic de botón para ejecutar una función setInterval para un temporizador de cuenta regresiva.
Error: 'Los ganchos solo se pueden llamar dentro del cuerpo de un componente de función. (...)'
Mi código:
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> ) }No puede llamar a un gancho dentro de otra función a menos que esa función sea un componente React.
Como desea iniciar el temporizador al presionar un botón, no necesita escuchar los efectos secundarios y, por lo tanto, no necesita llamar a useEffect, y simplemente iniciar el temporizador al presionar el botón.
Debe borrar el temporizador al desmontar el componente. Para esto, necesitará un useEffect , ya que React internamente activará la función de limpieza useEffect.
Sugeriría algo como esto:
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 )