React Native中onChangeText不生效 计时器达设定值无响应问题
问题原因
- 判断逻辑放错位置:
onHandleWork仅在用户输入文本时触发,计时器每秒累加计数时不会执行该判断,计数到达目标值时没有逻辑触发重置操作。 - 类型不匹配:
TextInput的onChangeText返回值是字符串类型,计数器存储的count是数字类型,全等判断===永远无法成立。 - 定时器操作错误:
setInterval返回的定时器ID没有单独存储,错误地将计数值count传给clearInterval,根本无法停止定时器,所有启停、重置按钮的定时器操作逻辑全部失效。 - 输入值未持久化存储:用户输入的工作时长仅在输入回调的临时参数里存在,回调执行完就被回收,计时器运行时拿不到用户设置的目标时长。
修复方案
- 单独存储定时器ID(挂在组件实例上即可,不需要放入state触发渲染),所有启停定时器的操作都使用该ID调用
clearInterval。 - 在state中新增
workTime字段,专门存储用户输入的目标工作时长,输入回调里只做值的存储和类型转换,不做计数判断。 - 将「计数是否到达目标值」的判断逻辑移到每次计数累加的
inc方法中,每次count更新后立刻判断是否满足重置条件。 - 相等判断前统一两边的数值类型,避免类型不一致导致判断失效。
修复后完整代码
import React from 'react' import {Button, StyleSheet,Text,View,TextInput} from 'react-native'; const styles = StyleSheet.create({ appContainer: { flex: 1, alignItems: 'center', justifyContent: 'center', }, counts: { fontSize: 48, } }) export default class App extends React.Component { // 定时器ID挂在实例上,不需要触发渲染 timer = null constructor() { super() this.state = { count: 0, start: true, workTime: null // 存储用户设置的工作时长 } } render() { return( <View style={styles.appContainer}> <Text style={styles.counts}>{this.state.count}</Text> <Button onPress={() => this.onButtonStop()} title="stop"/> <Button onPress={() => this.onButtonStart()} title="start"/> <Button onPress={() => this.onClear()}title="clear"/> <TextInput onChangeText={(value) => this.onHandleWork(value)} keyboardType="phone-pad" placeholder="time of work" /> <TextInput placeholder="enter your rest time"/> </View> ) } componentDidMount(){ // 存储定时器ID this.timer = setInterval(this.inc,1000) } componentWillUnmount() { // 组件卸载时清定时器防止内存泄漏 if (this.timer) clearInterval(this.timer) } onButtonStop(){ if (this.timer) clearInterval(this.timer) this.setState({start: false}) } onButtonStart(){ // 先清掉已有定时器防止重复创建 if (this.timer) clearInterval(this.timer) this.timer = setInterval(this.inc,1000) this.setState({start: true}) } onClear(){ if (this.timer) clearInterval(this.timer) this.setState({ count:0, start: false, }) } onHandleWork(value) { // 仅做输入值的存储,转成数字类型 const targetTime = Number(value) if (!isNaN(targetTime)) { this.setState({workTime: targetTime}) } } inc = () => { if (this.state.start) { this.setState(prevState => { const newCount = prevState.count + 1 // 每次计数更新后判断是否到达目标时长 if (prevState.workTime && newCount === prevState.workTime) { clearInterval(this.timer) return { count: 0, start: false } } return {count: newCount} }) } } }
内容的提问来源于stack exchange,提问作者ramanujans alkhazarim
相关产品推荐
相关产品推荐

