我遇到了我构建的组件的问题。如果两者都输入,则一个值(inclVal
)必须大于另一个值(exclVal
)。我想运行一个处理setTimeout()
的函数,这样在道具停止更改后它不会更新一秒,以确保它在用户输入时不会更改用户输入的值。为此,我在else
块中放置了一个clearTimeout()
,以防止在道具改变时使该功能执行以使其冗余。问题在于clearTimeout()
由于某些原因不起作用,只要输入if
块,即使在超时间隔内输入了else
块,更新功能仍在运行。React无状态组件clearTimeout似乎不起作用
该组件是一个无状态的功能组件,并且正在使用redux进行状态管理。我已经阅读了关于如何使这些工作成功的一堆,但似乎没有任何帮助。任何帮助表示赞赏!
下面是代码:
import React from 'react'
import PropTypes from 'prop-types'
import { connect } from 'react-redux'
import SelectPickerPulldown from '../../components/SelectPickerPulldown'
import TextInput from '../../components/TextInput'
import { odOptions } from '../../config/'
import { setODProperty } from '../../actions/odAnalyzerActions'
import { getConversion, getGreaterVal } from '../../utils/'
const InclusionExclusionOptions = ({ name,
analysisPoint,
paths,
exclVal,
exclUnit,
inclVal,
inclUnit,
getVal,
getUnit,
setSafeInclVal,
}) => {
const disabled = analysisPoint !== null || paths ? false : true
let inclEntryTimer = null
const exclCompare = getConversion(exclUnit)(exclVal)
const inclCompare = getConversion(inclUnit)(inclVal)
if (exclVal > 0 && inclVal > 0 && exclCompare > inclCompare) {
const safeInclVal = getGreaterVal(exclVal, exclUnit, inclUnit)
console.log('entering timeout');
inclEntryTimer = setTimeout(() => {
console.log('dispatching timeout action');
setSafeInclVal(safeInclVal)
}, 1000)
}
else {
console.log('clearing timeout');
clearTimeout(inclEntryTimer)
inclEntryTimer = null
}
return (
<div className="form-group" >
<h4>Inclusion/Exclusion Options</h4>
<ul className={name}>
<li className={`text-select-group ${disabled ? name + ' disabled' : name}`}>
<p>Exclusion Radius</p>
<div className="radius-setting">
<TextInput
type="number"
name="exclVal"
value={exclVal}
onChange={getVal}
/>
<SelectPickerPulldown
value={'exclUnit'}
options={odOptions.units}
selected={exclUnit}
getSelected={getUnit}
/>
</div>
</li>
<li className={`text-select-group ${disabled ? name + ' disabled' : name}`}>
<p>Inclusion Radius</p>
<div className="radius-setting">
<TextInput
type="number"
name="inclVal"
value={inclVal}
onChange={getVal}
/>
<SelectPickerPulldown
value={'inclUnit'}
options={odOptions.units}
selected={inclUnit}
getSelected={getUnit}
/>
</div>
</li>
</ul>
</div>
)
}
InclusionExclusionOptions.propTypes = {
name: PropTypes.string,
exclVal: PropTypes.number,
exclUnit: PropTypes.string,
inclVal: PropTypes.number,
inclUnit: PropTypes.string,
getVal: PropTypes.func,
getUnit: PropTypes.func,
}
const mapStateToProps = (state, ownProps) => {
const name = 'inclusion-exclusion-options'
const { analysisPoint,
paths,
exclVal,
exclUnit,
inclVal,
inclUnit } = state.odAnalyzerState
return {
name,
analysisPoint,
paths,
exclVal,
exclUnit,
inclVal,
inclUnit,
}
}
const mapDispatchToProps = dispatch => {
return {
getUnit: option => dispatch(setODProperty(option)),
getVal: (e, name) => dispatch(setODProperty({[name]: parseInt(e.target.value)})),
setSafeInclVal: safeInclVal => dispatch(setODProperty({inclVal: safeInclVal}))
}
}
export default connect(
mapStateToProps,
mapDispatchToProps)(InclusionExclusionOptions)
这里是更新的代码使用componentDidUpdate()
类成分:
class InclusionExclusionOptions extends React.Component{
constructor(props){
super(props)
this.inclEntryTimer = null
}
componentDidUpdate(props){
const { exclVal,
exclUnit,
inclVal,
inclUnit,
} = this.props
const exclCompare = getConversion(exclUnit)(exclVal)
const inclCompare = getConversion(inclUnit)(inclVal)
if (!!exclVal && !!inclVal && exclCompare > inclCompare) {
const safeInclVal = getGreaterVal(exclVal, exclUnit, inclUnit)
console.log('entering timeout')
this.inclEntryTimer = setTimeout(() => {
console.log('dispatching timeout action');
this.props.setSafeInclVal(safeInclVal)
}, 3000)
}
else {
console.log('clearing timeout');
clearTimeout(this.inclEntryTimer)
this.inclEntryTimer = null
}
}
render() {
const { name,
analysisPoint,
paths,
exclVal,
exclUnit,
inclVal,
inclUnit,
getVal,
getUnit,
} = this.props
const disabled = analysisPoint !== null || paths ? false : true
return (
<div className="form-group" >
<h4>Inclusion/Exclusion Options</h4>
<ul className={name}>
<li className={`text-select-group ${disabled ? name + ' disabled' : name}`}>
<p>Exclusion Radius</p>
<div className="radius-setting">
<TextInput
type="number"
name="exclVal"
value={exclVal}
onChange={getVal}
/>
<SelectPickerPulldown
value={'exclUnit'}
options={odOptions.units}
selected={exclUnit}
getSelected={getUnit}
/>
</div>
</li>
<li className={`text-select-group ${disabled ? name + ' disabled' : name}`}>
<p>Inclusion Radius</p>
<div className="radius-setting">
<TextInput
type="number"
name="inclVal"
value={inclVal}
onChange={getVal}
/>
<SelectPickerPulldown
value={'inclUnit'}
options={odOptions.units}
selected={inclUnit}
getSelected={getUnit}
/>
</div>
</li>
</ul>
</div>
)
}
}
每布兰登的建议下,我能得到超时只需清除清除它在宣布它之前。我打破了一个明确的超时功能
clearInclEntryTimer(){
clearTimeout(this.inclEntryTimer)
this.inclEntryTimer = null
}
然后把它称为在if
块的顶部和else
块。这很好。谢谢您的帮助!
你不应该像'setTimeout'表演渲染方法的内部副作用(和功能部件是有效_just_渲染方法)。如果你想做这样的事情,这应该是一个真正的类组件,而行为应该放在组件生命周期方法中。 – markerikson