Javascript clearInterval()在React Native中不工作-尝试从类转换为功能组件-计时器

Javascript clearInterval()在React Native中不工作-尝试从类转换为功能组件-计时器,javascript,react-native,timer,react-hooks,setinterval,Javascript,React Native,Timer,React Hooks,Setinterval,尝试在react native中制作秒表时,我使用类组件的工作代码,但尝试使用功能组件时,clearInterval()函数不工作 在此处修改之前,来自ReactNativeAcademy/Stopwatch的源代码 我只需要一个没有圈数的基本计时器,只有启动按钮/恢复按钮/停止按钮/重置按钮 我的代码的快捷url: 为了在基于类的组件中测试它,您可以在functional one下找到每个基于类的函数 我不知道,但可能有一种解决方案是在useEffect中包装setInterval,然后在st

尝试在react native中制作秒表时,我使用类组件的工作代码,但尝试使用功能组件时,
clearInterval()
函数不工作

在此处修改之前,来自ReactNativeAcademy/Stopwatch的源代码

我只需要一个没有圈数的基本计时器,只有启动按钮/恢复按钮/停止按钮/重置按钮 我的代码的快捷url: 为了在基于类的组件中测试它,您可以在functional one下找到每个基于类的函数

我不知道,但可能有一种解决方案是在useEffect中包装setInterval,然后在start和useEffect侦听该变量时,让一个新的状态变量将其切换为true

不用多说,下面是代码:

import React, { Component, useEffect, useState } from 'react';
import { StyleSheet, Text, View, TouchableOpacity } from 'react-native';
import moment from 'moment';

function Timer({ interval, style }) {
  const pad = (n) => (n < 10 ? `0${n}` : n);
  const duration = moment.duration(interval);
  const centiseconds = Math.floor(duration.milliseconds() / 10);

  return (
    <View style={styles.timerContainer}>
      <Text style={style}>{pad(duration.minutes())}:</Text>
      <Text style={style}>{pad(duration.seconds())},</Text>
      <Text style={style}>{pad(centiseconds)}</Text>
    </View>
  );
}

function RoundButton({ title, color, background, onPress }) {
  return (
    <TouchableOpacity onPress={onPress} style={[styles.button, { backgroundColor: background }]}>
      <View style={styles.buttonBorder}>
        <Text style={[styles.buttonTitle, { color }]}>{title}</Text>
      </View>
    </TouchableOpacity>
  );
}

function ButtonsRow({ children }) {
  return <View style={styles.buttonsRow}>{children}</View>;
}

// export default class App extends Component {
export default function App() {
  const [timer, setTimer] = useState(0);
  const [state, setState] = useState({
    start: 0,
    now: 0,
    currentTime: 0,
  });

  // constructor(props) {
  //   super(props);
  //   this.state = {
  //     start: 0,
  //     now: 0,
  //     currentTime: 0,
  //   };
  // }

  useEffect(() => {
    return () => {
      clearInterval(timer);
    };
  }, []);

  // componentWillUnmount() {
  //   clearInterval(this.timer);
  // }

  const startHandler = () => {
    const now = new Date().getTime();
    setState({
      start: now,
      now,
      currentTime: 0,
    });
    setInterval(
      setInterval(() => {
        setState((prev) => ({ ...prev, now: new Date().getTime() }));
      }, 100)
    );
  };

  // startHandler = () => {
  //   const now = new Date().getTime();
  //   this.setState({
  //     start: now,
  //     now,
  //     currentTime: 0,
  //   });
  //   this.timer = setInterval(() => {
  //     this.setState({ now: new Date().getTime() });
  //   }, 100);
  // };

  const stopHandler = () => {
    clearInterval(timer);
    const { currentTime, now, start } = state;
    setState((prev) => ({
      // ...prev,
      currentTime: currentTime + (now - start),
      start: 0,
      now: 0,
    }));
  };

  // stopHandler = () => {
  //   clearInterval(this.timer);
  //   const { currentTime, now, start } = this.state;
  //   this.setState({
  //     currentTime: currentTime + now - start,
  //     start: 0,
  //     now: 0,
  //   });
  // };

  const resetHandler = () => {
    setState({
      currentTime: 0,
      start: 0,
      now: 0,
    });
  };

  // resetHandler = () => {
  //   this.setState({
  //     currentTime: 0,
  //     start: 0,
  //     now: 0,
  //   });
  // };

  const resumeHandler = () => {
    const now = new Date().getTime();
    setState({
      start: now,
      now,
    });
    setTimer(
      setInterval(() => {
        setState((prev) => ({ ...prev, now: new Date().getTime() }));
      }, 100)
    );
  };

  // resumeHandler = () => {
  //   const now = new Date().getTime();
  //   this.setState({
  //     start: now,
  //     now,
  //   });
  //   this.timer = setInterval(() => {
  //     this.setState({ now: new Date().getTime() });
  //   }, 100);
  // };

  // render() {
  const { now, start, currentTime } = state;
  // const { now, start, currentTime } = this.state;

  return (
    <View style={styles.container}>
      <Timer interval={currentTime + (now - start)} style={styles.timer} />
      <ButtonsRow>
        <RoundButton title={'Start'} color={'#50D167'} background={'#1B361F'} onPress={startHandler} />
        <RoundButton title={'Stop'} color={'#E33935'} background={'#3C1715'} onPress={stopHandler} />
        <RoundButton title={'Reset'} color={'#FFFFFF'} background={'#3D3D3D'} onPress={resetHandler} />
        <RoundButton title={'Resume'} color={'#50D167'} background={'#1B361F'} onPress={resumeHandler} />
      </ButtonsRow>
    </View>
  );
}
// }

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#0D0D0D',
    alignItems: 'center',
    paddingTop: 130,
    paddingHorizontal: 20,
  },
  timer: {
    color: '#FFFFFF',
    fontSize: 76,
    fontWeight: '200',
    width: 110,
  },
  button: {
    width: 80,
    height: 80,
    borderRadius: 40,
    justifyContent: 'center',
    alignItems: 'center',
  },
  buttonTitle: {
    fontSize: 18,
  },
  buttonBorder: {
    width: 76,
    height: 76,
    borderRadius: 38,
    borderWidth: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
  buttonsRow: {
    flexDirection: 'row',
    alignSelf: 'stretch',
    justifyContent: 'space-between',
    marginTop: 80,
    marginBottom: 30,
  },
  timerContainer: {
    flexDirection: 'row',
  },
});
import React,{Component,useffect,useState}来自'React';
从“react native”导入{样式表、文本、视图、TouchableOpacity};
从“力矩”中导入力矩;
函数计时器({interval,style}){
常数pad=(n)=>(n<10?`0${n}`:n);
常数持续时间=时刻持续时间(间隔);
常数厘米秒=数学地板(持续时间毫秒()/10);
返回(
{pad(duration.minutes())}:
{pad(duration.seconds())},
{pad(厘米秒)}
);
}
函数RoundButton({标题、颜色、背景、onPress}){
返回(
{title}
);
}
函数按钮箭头({children}){
返回{children};
}
//导出默认类应用程序扩展组件{
导出默认函数App(){
const[timer,setTimer]=useState(0);
常量[状态,设置状态]=使用状态({
起点:0,
现在:0,,
当前时间:0,
});
//建造师(道具){
//超级(道具);
//此.state={
//起点:0,
//现在:0,,
//当前时间:0,
//   };
// }
useffect(()=>{
return()=>{
清除间隔(计时器);
};
}, []);
//组件将卸载(){
//clearInterval(这个计时器);
// }
常数startHandler=()=>{
const now=new Date().getTime();
设定状态({
开始:现在,
现在,
当前时间:0,
});
设定间隔(
设置间隔(()=>{
setState((prev)=>({…prev,现在:new Date().getTime()}));
}, 100)
);
};
//startHandler=()=>{
//const now=new Date().getTime();
//这是我的国家({
//开始:现在,
//现在,,
//当前时间:0,
//   });
//this.timer=setInterval(()=>{
//this.setState({now:new Date().getTime()});
//   }, 100);
// };
常量stopHandler=()=>{
清除间隔(计时器);
const{currentTime,now,start}=state;
设置状态((上一个)=>({
//…上一页,
currentTime:currentTime+(现在-开始),
起点:0,
现在:0,,
}));
};
//stopHandler=()=>{
//clearInterval(这个计时器);
//const{currentTime,now,start}=this.state;
//这是我的国家({
//currentTime:currentTime+now-开始,
//起点:0,
//现在:0,,
//   });
// };
常量resetHandler=()=>{
设定状态({
当前时间:0,
起点:0,
现在:0,,
});
};
//重置处理程序=()=>{
//这是我的国家({
//当前时间:0,
//起点:0,
//现在:0,,
//   });
// };
常量resumeHandler=()=>{
const now=new Date().getTime();
设定状态({
开始:现在,
现在,
});
设定计时器(
设置间隔(()=>{
setState((prev)=>({…prev,现在:new Date().getTime()}));
}, 100)
);
};
//简历处理程序=()=>{
//const now=new Date().getTime();
//这是我的国家({
//开始:现在,
//现在,,
//   });
//this.timer=setInterval(()=>{
//this.setState({now:new Date().getTime()});
//   }, 100);
// };
//render(){
const{now,start,currentTime}=state;
//const{now,start,currentTime}=this.state;
返回(
);
}
// }
const styles=StyleSheet.create({
容器:{
弹性:1,
背景颜色:“#0d0d”,
对齐项目:“居中”,
paddingTop:130,
水平方向:20,
},
计时器:{
颜色:“#FFFFFF”,
尺码:76,
fontWeight:'200',
宽度:110,
},
按钮:{
宽度:80,
身高:80,
边界半径:40,
为内容辩护:“中心”,
对齐项目:“居中”,
},
钮扣:{
尺码:18,
},
按钮顺序:{
宽度:76,
身高:76,
边界半径:38,
边框宽度:1,
为内容辩护:“中心”,
对齐项目:“居中”,
},
按钮箭头:{
flexDirection:'行',
自我定位:“拉伸”,
justifyContent:'之间的空间',
玛金托普:80,
marginBottom:30,
},
时间容器:{
flexDirection:'行',
},
});
试试看:

useEffect(() => {    
  clearInterval(timer);  
}, []);

当使用returninside useEffect时,代码仅在组件卸载时触发。

是的,我刚刚尝试过它…谢谢,但它不起作用。实际上,我们想在按下Stop时清除Interval,当组件也卸载时,但问题在于stopHandler函数中没有清除IntervalI,我刚刚看到了一个例子在setInterval中重新使用setInterval…我认为问题在于setInterval,而不是clearInterval。对不起,我在哪里这么做?在const startHandler中…setInterval是重复的。在startHandler中是的,找到了它而不是setTimer哦,天哪,这是一个多大的错误啊,我总是做最难的部分,而且会被Naming和打字错误抓住。非常感谢你,我他现在在工作